/dolfin.conf)?")
endif()
dolfin-1.3.0/bench/plot.py 0000644 0001750 0001750 00000020022 12263014601 015244 0 ustar johannr johannr #!/usr/bin/env python
"""
This script parses logs/bench.log and create plots for each case with
the timings function of time (date plot). It also creates a web page
index.html for easy viewing of the generated plots.
"""
# Copyright (C) 2010 Johannes Ring
#
# This file is part of DOLFIN.
#
# DOLFIN is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DOLFIN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DOLFIN. If not, see .
#
# First added: 2010-04-06
# Last changed: 2010-04-13
import os
import re
import time
import datetime
import textwrap
import numpy
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# Change some of the default Matplotlib parameters
plt.rcParams.update({'figure.figsize': [6, 4],
'font.size' : 10,
'axes.labelsize' : 10,
'axes.grid': True,
'text.fontsize' : 10,
'legend.fontsize' : 8,
'xtick.labelsize' : 8,
'ytick.labelsize' : 8,
})
# Write to web page index.html
outfile = open("index.html", "w")
outfile.write("DOLFIN Benchmarks
\n")
outfile.write("Last updated: %s.\n\n" % time.asctime())
# Open and read in logs/bench.log
benchlog = "logs/bench.log"
lines = open(benchlog, 'r').readlines()
benchmarks = {}
pattern = "\((.*)\)\s+(.*)\s+(.*)\s+\"(.*)\""
# Extract data from logfile
print "Parsing %s..." % benchlog
for line in lines:
match = re.search(pattern, line)
if match:
year, month, day, hour, minute, second = \
[int(i) for i in match.group(1).split(',')]
#date = datetime.datetime(year, month, day, hour, minute, second)
date = datetime.date(year, month, day)
name = match.group(2)
elapsed_time = float(match.group(3))
description = match.group(4)
if not name in benchmarks:
benchmarks[name] = [[date], [elapsed_time], description]
else:
benchmarks[name][0].append(date)
benchmarks[name][1].append(elapsed_time)
# Open and read in logs/milestones.log
milestones = []
milestoneslog = "logs/milestones.log"
if os.path.isfile(milestoneslog):
lines = open(milestoneslog, 'r').readlines()
for line in lines:
date = datetime.datetime.strptime(line.split()[0], "%Y-%m-%d")
progname = ' '.join(line.split()[1:])
milestones.append([date, progname])
# Get Matplotlib line markers for use later
markers = []
for m in plt.Line2D.markers:
try:
if len(m) == 1 and m != ' ':
markers.append(m)
except TypeError:
pass
year = datetime.timedelta(days=365)
month = datetime.timedelta(days=30)
week = datetime.timedelta(days=7)
today = datetime.date.today()
lasts = ['week', 'month', 'year', 'five years']
locators = [mdates.DayLocator(), mdates.DayLocator(interval=2),
mdates.MonthLocator(), mdates.YearLocator()]
date_fmts = ['%Y-%m-%d', '%d %b', '%b %Y', '%Y']
xmins = [today - week, today - month, today - year, today - 5*year]
outfile.write("All benchmarks
\n")
outfile.write("
\n")
outfile.write("\n")
def get_maxtime(dates, min_date, max_date, run_timings):
"""Return the maximum time between min_date and max_date"""
max_time = 0
for i, date in enumerate(dates):
if date < min_date:
continue
elif date > max_date:
break
else:
if max_time < run_timings[i]:
max_time = run_timings[i]
return max_time
# Create normalized plots with all benchmarks in same plot for
# last week, last month, last year, and last five years
print "Generating plots for all benchmarks..."
for last, locator, date_fmt, xmin in zip(lasts, locators, date_fmts, xmins):
fig = plt.figure()
ax = fig.gca()
num = 0
ymax = 0
for benchmark, values in benchmarks.items():
num += 1
dates = values[0]
run_timings = values[1]/numpy.linalg.norm(values[1])
ax.plot(dates, run_timings,
marker=markers[num % len(markers)], markersize=3,
label=benchmark)
ax.hold(True)
maxtime = get_maxtime(dates, xmin, today, run_timings)
if maxtime > ymax:
ymax = maxtime
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.DateFormatter(date_fmt))
ax.set_xlim(xmin, today)
ax.set_ylim(0, ymax)
# Add milestones to plot
for milestone in milestones:
milestone_num = mdates.date2num(milestone[0])
ax.annotate(milestone[1], xy=(milestone_num, 0.1E-10),
xycoords='data', xytext=(0, 30),
textcoords='offset points',
horizontalalignment='center',
verticalalignment='bottom',
style='italic', fontsize=6,
alpha=0.7, rotation='vertical',
arrowprops=dict(arrowstyle="->", alpha=0.3)
)
lgd = plt.legend(loc='best')
fig.autofmt_xdate()
plt.title("All benchmarks (last %s)" % last)
filename = "all_last_%s.png" % last.replace(' ', '_')
plt.savefig(filename, facecolor='#eeeeee')
# Add plots to web page
if last in ['week', 'year']:
outfile.write("  | \n" % filename)
else:
outfile.write("  |
\n" % filename)
outfile.write("
\n")
outfile.write("\n")
# Now create separate plots for every benchmark
for benchmark, values in benchmarks.items():
print "Generating plots for %s..." % benchmark
outfile.write("%s
\n" % benchmark)
outfile.write("
\n")
outfile.write("\n")
dates = values[0]
run_timings = values[1]
description = values[2]
# Wrap the lines in the description
description = textwrap.fill(description, width=30)
# Create plots for last week, last month, last year, and last five years
for last, locator, date_fmt, xmin in zip(lasts, locators, date_fmts, xmins):
fig = plt.figure()
ax = fig.gca()
ax.plot(dates, run_timings, marker='o', markersize=3)
ax.set_ylabel("time (seconds)")
maxtime = get_maxtime(dates, xmin, today, run_timings)
ax.set_ylim(0, maxtime + maxtime/2)
ax.legend((description,), loc='best')
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.DateFormatter(date_fmt))
ax.set_xlim(xmin, today)
# Add milestones to plot
for milestone in milestones:
milestone_num = mdates.date2num(milestone[0])
ax.annotate(milestone[1], xy=(milestone_num, 0.1E-10),
xycoords='data', xytext=(0, 30),
textcoords='offset points',
horizontalalignment='center',
verticalalignment='bottom',
style='italic', fontsize=6,
alpha=0.7, rotation='vertical',
arrowprops=dict(arrowstyle="->", alpha=0.3)
)
fig.autofmt_xdate()
plt.title("%s (last %s)" % (benchmark, last))
filename = "%s_last_%s.png" % (benchmark, last.replace(' ', '_'))
plt.savefig(filename, facecolor='#eeeeee')
# Add plots to web page
if last in ['week', 'year']:
outfile.write("  | \n" % filename)
else:
outfile.write("  |
\n" % filename)
outfile.write("
\n")
outfile.write("\n")
dolfin-1.3.0/bench/la/ 0000755 0001750 0001750 00000000000 12263014601 014314 5 ustar johannr johannr dolfin-1.3.0/bench/la/cusp/ 0000755 0001750 0001750 00000000000 12263014601 015266 5 ustar johannr johannr dolfin-1.3.0/bench/la/cusp/python/ 0000755 0001750 0001750 00000000000 12263014601 016607 5 ustar johannr johannr dolfin-1.3.0/bench/la/cusp/python/bench_la_cusp_python 0000755 0001750 0001750 00000004761 12263014601 022733 0 ustar johannr johannr #!/usr/bin/env python
# Copyright (C) 2012 Anders Logg
#
# This file is part of DOLFIN.
#
# DOLFIN is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DOLFIN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DOLFIN. If not, see .
#
# First added: 2012-03-09
# Last changed: 2012-04-25
from dolfin import *
from time import time
SIZE = 32
NUM_REPS = 3
print "Solving the linear system for Poisson's equation using PETSc CUSP"
# Check that we have the PETSc Cusp backend
if not has_linear_algebra_backend("PETScCusp"):
print "Cannot run this benchmark since PETSc Cusp is not available."
print "BENCH: 0.0"
exit(0)
# Function for running test
def run_bench(linear_algebra_backend):
info("")
info("Linear algebra backend: %s" % linear_algebra_backend)
# Set linear algebra backend
parameters["linear_algebra_backend"] = linear_algebra_backend
# Create matrix and vector
print "Assembling matrix and vector"
mesh = UnitCube(SIZE, SIZE, SIZE)
V = FunctionSpace(mesh, "Lagrange", 1)
u = TrialFunction(V)
v = TestFunction(V)
f = Constant(1.0)
a = dot(grad(u), grad(v))*dx
L = f*v*dx
bc = DirichletBC(V, 0.0, DomainBoundary())
A, b = assemble_system(a, L, bc)
# Create linear solver
solver = KrylovSolver("cg", "jacobi")
# Use hack to get around PETSc Cusp bug
solver.parameters["use_petsc_cusp_hack"] = True
# Solve linear system
info("Solving linear system %d times" % NUM_REPS)
x = Vector()
cpu_time = time()
for i in range(NUM_REPS):
x.zero()
solver.solve(A, x, b)
print "residual =", residual(A, x, b)
cpu_time = (time() - cpu_time) / float(NUM_REPS)
return cpu_time
# Run benchmarks
cpu_time_petsc_cusp = run_bench("PETScCusp")
cpu_time_petsc = run_bench("PETSc")
# Compute speedup
speedup = cpu_time_petsc / cpu_time_petsc_cusp
# Report results
print
print "PETSc: ", cpu_time_petsc
print "PETSc Cusp:", cpu_time_petsc_cusp
print "Speedup: ", speedup
print
print "BENCH: ", speedup
dolfin-1.3.0/bench/la/vector/ 0000755 0001750 0001750 00000000000 12263014601 015616 5 ustar johannr johannr dolfin-1.3.0/bench/la/vector/access/ 0000755 0001750 0001750 00000000000 12263014601 017057 5 ustar johannr johannr dolfin-1.3.0/bench/la/vector/access/cpp/ 0000755 0001750 0001750 00000000000 12263015065 017646 5 ustar johannr johannr dolfin-1.3.0/bench/la/vector/access/cpp/CMakeLists.txt 0000644 0001750 0001750 00000002026 12263015065 022406 0 ustar johannr johannr # This file is automatically generated by running
#
# cmake/scripts/generate-cmakefiles
#
# Require CMake 2.8
cmake_minimum_required(VERSION 2.8)
set(PROJECT_NAME bench_la_vector_access_cpp)
project(${PROJECT_NAME})
# Set verbose output while testing CMake
#set(CMAKE_VERBOSE_MAKEFILE 1)
# Set CMake behavior
cmake_policy(SET CMP0004 OLD)
# Get DOLFIN configuration data (DOLFINConfig.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
find_package(DOLFIN)
# Default build type (can be overridden by user)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
endif()
# Compiler definitions
add_definitions(${DOLFIN_CXX_DEFINITIONS})
# Include directories
include_directories(${DOLFIN_INCLUDE_DIRS})
include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
# Executable
add_executable(${PROJECT_NAME} main.cpp)
# Target libraries
target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
dolfin-1.3.0/bench/la/vector/access/cpp/main.cpp 0000644 0001750 0001750 00000002401 12263014601 021266 0 ustar johannr johannr // Copyright (C) 2010 Anders Logg
//
// This file is part of DOLFIN.
//
// DOLFIN is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// DOLFIN is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see .
//
// Modified by Anders Logg, 2010.
//
// First added: 2010-03-30
// Last changed: 2010-05-03
#include
using namespace dolfin;
#define SIZE 10000000
#define NUM_REPS 100
int main(int argc, char* argv[])
{
info("Accessing vector of size %d (%d repetitions)",
SIZE, NUM_REPS);
parameters.parse(argc, argv);
Vector x(SIZE);
x.zero();
double sum = 0.0;
for (unsigned int i = 0; i < NUM_REPS; i++)
for (unsigned int j = 0; j < SIZE; j++)
sum += x[j];
dolfin::cout << "Sum is " << sum << dolfin::endl;
return 0;
}
dolfin-1.3.0/bench/la/vector/assignment/ 0000755 0001750 0001750 00000000000 12263014601 017766 5 ustar johannr johannr dolfin-1.3.0/bench/la/vector/assignment/cpp/ 0000755 0001750 0001750 00000000000 12263015065 020555 5 ustar johannr johannr dolfin-1.3.0/bench/la/vector/assignment/cpp/CMakeLists.txt 0000644 0001750 0001750 00000002032 12263015065 023312 0 ustar johannr johannr # This file is automatically generated by running
#
# cmake/scripts/generate-cmakefiles
#
# Require CMake 2.8
cmake_minimum_required(VERSION 2.8)
set(PROJECT_NAME bench_la_vector_assignment_cpp)
project(${PROJECT_NAME})
# Set verbose output while testing CMake
#set(CMAKE_VERBOSE_MAKEFILE 1)
# Set CMake behavior
cmake_policy(SET CMP0004 OLD)
# Get DOLFIN configuration data (DOLFINConfig.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
find_package(DOLFIN)
# Default build type (can be overridden by user)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
endif()
# Compiler definitions
add_definitions(${DOLFIN_CXX_DEFINITIONS})
# Include directories
include_directories(${DOLFIN_INCLUDE_DIRS})
include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
# Executable
add_executable(${PROJECT_NAME} main.cpp)
# Target libraries
target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
dolfin-1.3.0/bench/la/vector/assignment/cpp/main.cpp 0000644 0001750 0001750 00000002271 12263014601 022202 0 ustar johannr johannr // Copyright (C) 2006 Garth N. Wells
//
// This file is part of DOLFIN.
//
// DOLFIN is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// DOLFIN is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see .
//
// Modified by Anders Logg, 2010.
//
// First added: 2006-08-18
// Last changed: 2010-05-03
#include
using namespace dolfin;
#define NUM_REPS 100
#define SIZE 10000000
int main(int argc, char* argv[])
{
info("Assigning to vector of size %d (%d repetitions)",
SIZE, NUM_REPS);
parameters.parse(argc, argv);
Vector x(SIZE);
for (unsigned int i = 0; i < NUM_REPS; i++)
for (unsigned int j = 0; j < SIZE; j++)
x.setitem(j, 1.0);
return 0;
}
dolfin-1.3.0/bench/common/ 0000755 0001750 0001750 00000000000 12263014601 015210 5 ustar johannr johannr dolfin-1.3.0/bench/common/progress/ 0000755 0001750 0001750 00000000000 12263014601 017054 5 ustar johannr johannr dolfin-1.3.0/bench/common/progress/cpp/ 0000755 0001750 0001750 00000000000 12263015065 017643 5 ustar johannr johannr dolfin-1.3.0/bench/common/progress/cpp/CMakeLists.txt 0000644 0001750 0001750 00000002025 12263015065 022402 0 ustar johannr johannr # This file is automatically generated by running
#
# cmake/scripts/generate-cmakefiles
#
# Require CMake 2.8
cmake_minimum_required(VERSION 2.8)
set(PROJECT_NAME bench_common_progress_cpp)
project(${PROJECT_NAME})
# Set verbose output while testing CMake
#set(CMAKE_VERBOSE_MAKEFILE 1)
# Set CMake behavior
cmake_policy(SET CMP0004 OLD)
# Get DOLFIN configuration data (DOLFINConfig.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
find_package(DOLFIN)
# Default build type (can be overridden by user)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
endif()
# Compiler definitions
add_definitions(${DOLFIN_CXX_DEFINITIONS})
# Include directories
include_directories(${DOLFIN_INCLUDE_DIRS})
include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
# Executable
add_executable(${PROJECT_NAME} main.cpp)
# Target libraries
target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
dolfin-1.3.0/bench/common/progress/cpp/main.cpp 0000644 0001750 0001750 00000002324 12263014601 021267 0 ustar johannr johannr // Copyright (C) 2010 Anders Logg
//
// This file is part of DOLFIN.
//
// DOLFIN is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// DOLFIN is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see .
//
// First added: 2010-06-29
// Last changed: 2010-11-16
#include
using namespace dolfin;
#define NUM_REPS 5
#define SIZE 500000000
int main(int argc, char* argv[])
{
info("Creating progress bar with %d steps (%d repetitions)",
SIZE, NUM_REPS);
for (int i = 0; i < NUM_REPS; i++)
{
Progress p("Stepping", SIZE);
double sum = 0.0;
for (int j = 0; j < SIZE; j++)
{
sum += 0.1;
p++;
}
dolfin::cout << "sum = " << sum << dolfin::endl;
}
return 0;
}
dolfin-1.3.0/bench/common/timing/ 0000755 0001750 0001750 00000000000 12263014601 016477 5 ustar johannr johannr dolfin-1.3.0/bench/common/timing/cpp/ 0000755 0001750 0001750 00000000000 12263015065 017266 5 ustar johannr johannr dolfin-1.3.0/bench/common/timing/cpp/CMakeLists.txt 0000644 0001750 0001750 00000002023 12263015065 022023 0 ustar johannr johannr # This file is automatically generated by running
#
# cmake/scripts/generate-cmakefiles
#
# Require CMake 2.8
cmake_minimum_required(VERSION 2.8)
set(PROJECT_NAME bench_common_timing_cpp)
project(${PROJECT_NAME})
# Set verbose output while testing CMake
#set(CMAKE_VERBOSE_MAKEFILE 1)
# Set CMake behavior
cmake_policy(SET CMP0004 OLD)
# Get DOLFIN configuration data (DOLFINConfig.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
find_package(DOLFIN)
# Default build type (can be overridden by user)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
endif()
# Compiler definitions
add_definitions(${DOLFIN_CXX_DEFINITIONS})
# Include directories
include_directories(${DOLFIN_INCLUDE_DIRS})
include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
# Executable
add_executable(${PROJECT_NAME} main.cpp)
# Target libraries
target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
dolfin-1.3.0/bench/common/timing/cpp/main.cpp 0000644 0001750 0001750 00000002757 12263014601 020724 0 ustar johannr johannr // Copyright (C) 2010 Anders Logg
//
// This file is part of DOLFIN.
//
// DOLFIN is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// DOLFIN is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see .
//
// First added: 2010-11-16
// Last changed: 2010-11-16
#include
using namespace dolfin;
#define NUM_REPS 10000000
int main(int argc, char* argv[])
{
info("Timing access and registration of timings (%d repetitions)", NUM_REPS);
// Access to timer
double sum = 0.0;
double t0 = time();
double t1 = t0;
Timer timer_function("time() function");
for (int i = 0; i < NUM_REPS; i++)
{
t0 = time();
t1 = time();
sum += t1 - t0;
}
timer_function.stop();
dolfin::cout << "sum = " << sum << dolfin::endl << dolfin::endl;
// Test timer
Timer timer_loop("timer start/stop");
Timer timer_class("Timer class");
for (int i = 0; i < NUM_REPS; i++)
{
timer_loop.start();
timer_loop.stop();
}
timer_class.stop();
summary();
return 0;
}
dolfin-1.3.0/bench/geometry/ 0000755 0001750 0001750 00000000000 12263014601 015553 5 ustar johannr johannr dolfin-1.3.0/bench/geometry/bounding_box_tree_build/ 0000755 0001750 0001750 00000000000 12263014601 022426 5 ustar johannr johannr dolfin-1.3.0/bench/geometry/bounding_box_tree_build/cpp/ 0000755 0001750 0001750 00000000000 12263015065 023215 5 ustar johannr johannr dolfin-1.3.0/bench/geometry/bounding_box_tree_build/cpp/CMakeLists.txt 0000644 0001750 0001750 00000002046 12263015065 025757 0 ustar johannr johannr # This file is automatically generated by running
#
# cmake/scripts/generate-cmakefiles
#
# Require CMake 2.8
cmake_minimum_required(VERSION 2.8)
set(PROJECT_NAME bench_geometry_bounding_box_tree_build_cpp)
project(${PROJECT_NAME})
# Set verbose output while testing CMake
#set(CMAKE_VERBOSE_MAKEFILE 1)
# Set CMake behavior
cmake_policy(SET CMP0004 OLD)
# Get DOLFIN configuration data (DOLFINConfig.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
find_package(DOLFIN)
# Default build type (can be overridden by user)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
endif()
# Compiler definitions
add_definitions(${DOLFIN_CXX_DEFINITIONS})
# Include directories
include_directories(${DOLFIN_INCLUDE_DIRS})
include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
# Executable
add_executable(${PROJECT_NAME} main.cpp)
# Target libraries
target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
dolfin-1.3.0/bench/geometry/bounding_box_tree_build/cpp/main.cpp 0000644 0001750 0001750 00000002306 12263014601 024641 0 ustar johannr johannr // Copyright (C) 2013 Anders Logg
//
// This file is part of DOLFIN.
//
// DOLFIN is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// DOLFIN is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see .
//
// This benchmark measures the performance of building a BoundingBoxTree (and
// one call to compute_entities, which is dominated by building).
//
// First added: 2013-04-18
// Last changed: 2013-06-25
#include
#include
using namespace dolfin;
#define SIZE 128
int main(int argc, char* argv[])
{
// Create mesh
UnitCubeMesh mesh(SIZE, SIZE, SIZE);
// Create and build tree
tic();
BoundingBoxTree tree;
tree.build(mesh);
info("BENCH %g", toc());
return 0;
}
dolfin-1.3.0/bench/geometry/bounding_box_tree_compute_entity_collisions/ 0000755 0001750 0001750 00000000000 12263014601 026635 5 ustar johannr johannr dolfin-1.3.0/bench/geometry/bounding_box_tree_compute_entity_collisions/cpp/ 0000755 0001750 0001750 00000000000 12263015065 027424 5 ustar johannr johannr dolfin-1.3.0/bench/geometry/bounding_box_tree_compute_entity_collisions/cpp/CMakeLists.txt 0000644 0001750 0001750 00000002072 12263015065 032165 0 ustar johannr johannr # This file is automatically generated by running
#
# cmake/scripts/generate-cmakefiles
#
# Require CMake 2.8
cmake_minimum_required(VERSION 2.8)
set(PROJECT_NAME bench_geometry_bounding_box_tree_compute_entity_collisions_cpp)
project(${PROJECT_NAME})
# Set verbose output while testing CMake
#set(CMAKE_VERBOSE_MAKEFILE 1)
# Set CMake behavior
cmake_policy(SET CMP0004 OLD)
# Get DOLFIN configuration data (DOLFINConfig.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
find_package(DOLFIN)
# Default build type (can be overridden by user)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
endif()
# Compiler definitions
add_definitions(${DOLFIN_CXX_DEFINITIONS})
# Include directories
include_directories(${DOLFIN_INCLUDE_DIRS})
include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
# Executable
add_executable(${PROJECT_NAME} main.cpp)
# Target libraries
target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
dolfin-1.3.0/bench/geometry/bounding_box_tree_compute_entity_collisions/cpp/main.cpp 0000644 0001750 0001750 00000003131 12263014601 031045 0 ustar johannr johannr // Copyright (C) 2013 Anders Logg
//
// This file is part of DOLFIN.
//
// DOLFIN is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// DOLFIN is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see .
//
// This benchmark measures the performance of compute_entity_collisions.
//
// First added: 2013-05-23
// Last changed: 2013-09-04
#include
#include
using namespace dolfin;
#define NUM_REPS 5000000
#define SIZE 64
int main(int argc, char* argv[])
{
// Create mesh
UnitCubeMesh mesh(SIZE, SIZE, SIZE);
// First call
BoundingBoxTree tree;
tree.build(mesh);
Point point(0.0, 0.0, 0.0);
tree.compute_entity_collisions(point);
// Call repeatedly
tic();
for (int i = 0; i < NUM_REPS; i++)
{
point.coordinates()[0] += 1.0 / static_cast(NUM_REPS);
point.coordinates()[1] += 1.0 / static_cast(NUM_REPS);
point.coordinates()[2] += 1.0 / static_cast(NUM_REPS);
std::vector entities = tree.compute_entity_collisions(point);
}
const double t = toc();
// Report result
info("BENCH %g", t);
return 0;
}
dolfin-1.3.0/bench/geometry/bounding_box_tree_compute_closest_entity/ 0000755 0001750 0001750 00000000000 12263014601 026133 5 ustar johannr johannr dolfin-1.3.0/bench/geometry/bounding_box_tree_compute_closest_entity/cpp/ 0000755 0001750 0001750 00000000000 12263015065 026722 5 ustar johannr johannr dolfin-1.3.0/bench/geometry/bounding_box_tree_compute_closest_entity/cpp/CMakeLists.txt 0000644 0001750 0001750 00000002067 12263015065 031467 0 ustar johannr johannr # This file is automatically generated by running
#
# cmake/scripts/generate-cmakefiles
#
# Require CMake 2.8
cmake_minimum_required(VERSION 2.8)
set(PROJECT_NAME bench_geometry_bounding_box_tree_compute_closest_entity_cpp)
project(${PROJECT_NAME})
# Set verbose output while testing CMake
#set(CMAKE_VERBOSE_MAKEFILE 1)
# Set CMake behavior
cmake_policy(SET CMP0004 OLD)
# Get DOLFIN configuration data (DOLFINConfig.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
find_package(DOLFIN)
# Default build type (can be overridden by user)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
endif()
# Compiler definitions
add_definitions(${DOLFIN_CXX_DEFINITIONS})
# Include directories
include_directories(${DOLFIN_INCLUDE_DIRS})
include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
# Executable
add_executable(${PROJECT_NAME} main.cpp)
# Target libraries
target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
dolfin-1.3.0/bench/geometry/bounding_box_tree_compute_closest_entity/cpp/main.cpp 0000644 0001750 0001750 00000002747 12263014601 030357 0 ustar johannr johannr // Copyright (C) 2013 Anders Logg
//
// This file is part of DOLFIN.
//
// DOLFIN is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// DOLFIN is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with DOLFIN. If not, see .
//
// This benchmark measures the performance of compute_entity_collisions.
//
// First added: 2013-05-23
// Last changed: 2013-09-04
#include
#include
using namespace dolfin;
#define NUM_REPS 1000000
#define SIZE 64
int main(int argc, char* argv[])
{
// Create mesh
UnitCubeMesh mesh(SIZE, SIZE, SIZE);
// First call
BoundingBoxTree tree;
tree.build(mesh);
Point point(-1.0, -1.0, 0.0);
tree.compute_closest_entity(point);
cout << "Built tree, searching for closest point" << endl;
// Call repeatedly
tic();
for (int i = 0; i < NUM_REPS; i++)
{
tree.compute_closest_entity(point);
point.coordinates()[1] += 2.0 / static_cast(NUM_REPS);
}
const double t = toc();
// Report result
info("BENCH %g", t);
return 0;
}
dolfin-1.3.0/bench/fem/ 0000755 0001750 0001750 00000000000 12263014601 014467 5 ustar johannr johannr dolfin-1.3.0/bench/fem/multicore/ 0000755 0001750 0001750 00000000000 12263014601 016472 5 ustar johannr johannr dolfin-1.3.0/bench/fem/multicore/cpp/ 0000755 0001750 0001750 00000000000 12263015065 017261 5 ustar johannr johannr dolfin-1.3.0/bench/fem/multicore/cpp/Poisson.ufl 0000644 0001750 0001750 00000000254 12263014601 021417 0 ustar johannr johannr # Standard Poisson bilinear form
element = FiniteElement("Lagrange", tetrahedron, 1)
u = TrialFunction(element)
v = TestFunction(element)
a = inner(grad(u), grad(v))*dx
dolfin-1.3.0/bench/fem/multicore/cpp/NavierStokes.ufl 0000644 0001750 0001750 00000001075 12263014601 022404 0 ustar johannr johannr # The bilinear form for a stabilized formulation of Navier-Stokes
element = VectorElement("Lagrange", tetrahedron, 1)
constant_scalar = FiniteElement("Discontinuous Lagrange", tetrahedron, 0)
v = TestFunction(element)
u = TrialFunction(element)
w = Coefficient(element)
d1 = Coefficient(constant_scalar)
d2 = Coefficient(constant_scalar)
k = Coefficient(constant_scalar)
nu = Coefficient(constant_scalar)
a = inner(u, v)*dx + 0.5*k*nu*inner(grad(u), grad(v))*dx + 0.5*k*inner(grad(u)*w, v)*dx \
+ d1*0.5*k*dot(grad(u)*w, grad(v)*w)*dx + d2*0.5*k*div(u)*div(v)*dx
dolfin-1.3.0/bench/fem/multicore/cpp/CMakeLists.txt 0000644 0001750 0001750 00000002023 12263015065 022016 0 ustar johannr johannr # This file is automatically generated by running
#
# cmake/scripts/generate-cmakefiles
#
# Require CMake 2.8
cmake_minimum_required(VERSION 2.8)
set(PROJECT_NAME bench_fem_multicore_cpp)
project(${PROJECT_NAME})
# Set verbose output while testing CMake
#set(CMAKE_VERBOSE_MAKEFILE 1)
# Set CMake behavior
cmake_policy(SET CMP0004 OLD)
# Get DOLFIN configuration data (DOLFINConfig.cmake must be in DOLFIN_CMAKE_CONFIG_PATH)
find_package(DOLFIN)
# Default build type (can be overridden by user)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
endif()
# Compiler definitions
add_definitions(${DOLFIN_CXX_DEFINITIONS})
# Include directories
include_directories(${DOLFIN_INCLUDE_DIRS})
include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
# Executable
add_executable(${PROJECT_NAME} main.cpp)
# Target libraries
target_link_libraries(${PROJECT_NAME} ${DOLFIN_LIBRARIES} ${DOLFIN_3RD_PARTY_LIBRARIES})
dolfin-1.3.0/bench/fem/multicore/cpp/NavierStokes.h 0000644 0001750 0001750 00000657151 12263015046 022065 0 ustar johannr johannr // This code conforms with the UFC specification version 2.3.0
// and was automatically generated by FFC version 1.3.0.
//
// This code was generated with the option '-l dolfin' and
// contains DOLFIN-specific wrappers that depend on DOLFIN.
//
// This code was generated with the following parameters:
//
// cache_dir: ''
// convert_exceptions_to_warnings: False
// cpp_optimize: True
// cpp_optimize_flags: '-O2'
// epsilon: 1e-14
// error_control: False
// form_postfix: True
// format: 'dolfin'
// log_level: 10
// log_prefix: ''
// no_ferari: True
// optimize: True
// output_dir: '.'
// precision: 15
// quadrature_degree: 'auto'
// quadrature_rule: 'auto'
// representation: 'auto'
// restrict_keyword: ''
// split: False
#ifndef __NAVIERSTOKES_H
#define __NAVIERSTOKES_H
#include
#include
#include
#include
/// This class defines the interface for a finite element.
class navierstokes_finite_element_0: public ufc::finite_element
{
public:
/// Constructor
navierstokes_finite_element_0() : ufc::finite_element()
{
// Do nothing
}
/// Destructor
virtual ~navierstokes_finite_element_0()
{
// Do nothing
}
/// Return a string identifying the finite element
virtual const char* signature() const
{
return "FiniteElement('Discontinuous Lagrange', Domain(Cell('tetrahedron', 3), 'tetrahedron_multiverse', 3, 3), 0, None)";
}
/// Return the cell shape
virtual ufc::shape cell_shape() const
{
return ufc::tetrahedron;
}
/// Return the topological dimension of the cell shape
virtual std::size_t topological_dimension() const
{
return 3;
}
/// Return the geometric dimension of the cell shape
virtual std::size_t geometric_dimension() const
{
return 3;
}
/// Return the dimension of the finite element function space
virtual std::size_t space_dimension() const
{
return 1;
}
/// Return the rank of the value space
virtual std::size_t value_rank() const
{
return 0;
}
/// Return the dimension of the value space for axis i
virtual std::size_t value_dimension(std::size_t i) const
{
return 1;
}
/// Evaluate basis function i at given point x in cell
virtual void evaluate_basis(std::size_t i,
double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Compute Jacobian
double J[9];
compute_jacobian_tetrahedron_3d(J, vertex_coordinates);
// Compute Jacobian inverse and determinant
double K[9];
double detJ;
compute_jacobian_inverse_tetrahedron_3d(K, detJ, J);
// Compute constants
// Compute subdeterminants
// Get coordinates and map to the reference (FIAT) element
// Reset values
*values = 0.0;
// Array of basisvalues
double basisvalues[1] = {0.0};
// Declare helper variables
// Compute basisvalues
basisvalues[0] = 1.0;
// Table(s) of coefficients
static const double coefficients0[1] = \
{1.0};
// Compute value(s)
for (unsigned int r = 0; r < 1; r++)
{
*values += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
}
/// Evaluate all basis functions at given point x in cell
virtual void evaluate_basis_all(double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Element is constant, calling evaluate_basis.
evaluate_basis(0, values, x, vertex_coordinates, cell_orientation);
}
/// Evaluate order n derivatives of basis function i at given point x in cell
virtual void evaluate_basis_derivatives(std::size_t i,
std::size_t n,
double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Compute number of derivatives.
unsigned int num_derivatives = 1;
for (unsigned int r = 0; r < n; r++)
{
num_derivatives *= 3;
}// end loop over 'r'
// Reset values. Assuming that values is always an array.
for (unsigned int r = 0; r < num_derivatives; r++)
{
values[r] = 0.0;
}// end loop over 'r'
// Call evaluate_basis if order of derivatives is equal to zero.
if (n == 0)
{
evaluate_basis(i, values, x, vertex_coordinates, cell_orientation);
return ;
}
// If order of derivatives is greater than the maximum polynomial degree, return zeros.
if (n > 0)
{
return ;
}
}
/// Evaluate order n derivatives of all basis functions at given point x in cell
virtual void evaluate_basis_derivatives_all(std::size_t n,
double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Element is constant, calling evaluate_basis_derivatives.
evaluate_basis_derivatives(0, n, values, x, vertex_coordinates, cell_orientation);
}
/// Evaluate linear functional for dof i on the function f
virtual double evaluate_dof(std::size_t i,
const ufc::function& f,
const double* vertex_coordinates,
int cell_orientation,
const ufc::cell& c) const
{
// Declare variables for result of evaluation
double vals[1];
// Declare variable for physical coordinates
double y[3];
switch (i)
{
case 0:
{
y[0] = 0.25*vertex_coordinates[0] + 0.25*vertex_coordinates[3] + 0.25*vertex_coordinates[6] + 0.25*vertex_coordinates[9];
y[1] = 0.25*vertex_coordinates[1] + 0.25*vertex_coordinates[4] + 0.25*vertex_coordinates[7] + 0.25*vertex_coordinates[10];
y[2] = 0.25*vertex_coordinates[2] + 0.25*vertex_coordinates[5] + 0.25*vertex_coordinates[8] + 0.25*vertex_coordinates[11];
f.evaluate(vals, y, c);
return vals[0];
break;
}
}
return 0.0;
}
/// Evaluate linear functionals for all dofs on the function f
virtual void evaluate_dofs(double* values,
const ufc::function& f,
const double* vertex_coordinates,
int cell_orientation,
const ufc::cell& c) const
{
// Declare variables for result of evaluation
double vals[1];
// Declare variable for physical coordinates
double y[3];
y[0] = 0.25*vertex_coordinates[0] + 0.25*vertex_coordinates[3] + 0.25*vertex_coordinates[6] + 0.25*vertex_coordinates[9];
y[1] = 0.25*vertex_coordinates[1] + 0.25*vertex_coordinates[4] + 0.25*vertex_coordinates[7] + 0.25*vertex_coordinates[10];
y[2] = 0.25*vertex_coordinates[2] + 0.25*vertex_coordinates[5] + 0.25*vertex_coordinates[8] + 0.25*vertex_coordinates[11];
f.evaluate(vals, y, c);
values[0] = vals[0];
}
/// Interpolate vertex values from dof values
virtual void interpolate_vertex_values(double* vertex_values,
const double* dof_values,
const double* vertex_coordinates,
int cell_orientation,
const ufc::cell& c) const
{
// Evaluate function and change variables
vertex_values[0] = dof_values[0];
vertex_values[1] = dof_values[0];
vertex_values[2] = dof_values[0];
vertex_values[3] = dof_values[0];
}
/// Map coordinate xhat from reference cell to coordinate x in cell
virtual void map_from_reference_cell(double* x,
const double* xhat,
const ufc::cell& c) const
{
throw std::runtime_error("map_from_reference_cell not yet implemented.");
}
/// Map from coordinate x in cell to coordinate xhat in reference cell
virtual void map_to_reference_cell(double* xhat,
const double* x,
const ufc::cell& c) const
{
throw std::runtime_error("map_to_reference_cell not yet implemented.");
}
/// Return the number of sub elements (for a mixed element)
virtual std::size_t num_sub_elements() const
{
return 0;
}
/// Create a new finite element for sub element i (for a mixed element)
virtual ufc::finite_element* create_sub_element(std::size_t i) const
{
return 0;
}
/// Create a new class instance
virtual ufc::finite_element* create() const
{
return new navierstokes_finite_element_0();
}
};
/// This class defines the interface for a finite element.
class navierstokes_finite_element_1: public ufc::finite_element
{
public:
/// Constructor
navierstokes_finite_element_1() : ufc::finite_element()
{
// Do nothing
}
/// Destructor
virtual ~navierstokes_finite_element_1()
{
// Do nothing
}
/// Return a string identifying the finite element
virtual const char* signature() const
{
return "FiniteElement('Lagrange', Domain(Cell('tetrahedron', 3), 'tetrahedron_multiverse', 3, 3), 1, None)";
}
/// Return the cell shape
virtual ufc::shape cell_shape() const
{
return ufc::tetrahedron;
}
/// Return the topological dimension of the cell shape
virtual std::size_t topological_dimension() const
{
return 3;
}
/// Return the geometric dimension of the cell shape
virtual std::size_t geometric_dimension() const
{
return 3;
}
/// Return the dimension of the finite element function space
virtual std::size_t space_dimension() const
{
return 4;
}
/// Return the rank of the value space
virtual std::size_t value_rank() const
{
return 0;
}
/// Return the dimension of the value space for axis i
virtual std::size_t value_dimension(std::size_t i) const
{
return 1;
}
/// Evaluate basis function i at given point x in cell
virtual void evaluate_basis(std::size_t i,
double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Compute Jacobian
double J[9];
compute_jacobian_tetrahedron_3d(J, vertex_coordinates);
// Compute Jacobian inverse and determinant
double K[9];
double detJ;
compute_jacobian_inverse_tetrahedron_3d(K, detJ, J);
// Compute constants
const double C0 = vertex_coordinates[9] + vertex_coordinates[6] + vertex_coordinates[3] - vertex_coordinates[0];
const double C1 = vertex_coordinates[10] + vertex_coordinates[7] + vertex_coordinates[4] - vertex_coordinates[1];
const double C2 = vertex_coordinates[11] + vertex_coordinates[8] + vertex_coordinates[5] - vertex_coordinates[2];
// Compute subdeterminants
const double d_00 = J[4]*J[8] - J[5]*J[7];
const double d_01 = J[5]*J[6] - J[3]*J[8];
const double d_02 = J[3]*J[7] - J[4]*J[6];
const double d_10 = J[2]*J[7] - J[1]*J[8];
const double d_11 = J[0]*J[8] - J[2]*J[6];
const double d_12 = J[1]*J[6] - J[0]*J[7];
const double d_20 = J[1]*J[5] - J[2]*J[4];
const double d_21 = J[2]*J[3] - J[0]*J[5];
const double d_22 = J[0]*J[4] - J[1]*J[3];
// Get coordinates and map to the reference (FIAT) element
double X = (d_00*(2.0*x[0] - C0) + d_10*(2.0*x[1] - C1) + d_20*(2.0*x[2] - C2)) / detJ;
double Y = (d_01*(2.0*x[0] - C0) + d_11*(2.0*x[1] - C1) + d_21*(2.0*x[2] - C2)) / detJ;
double Z = (d_02*(2.0*x[0] - C0) + d_12*(2.0*x[1] - C1) + d_22*(2.0*x[2] - C2)) / detJ;
// Reset values
*values = 0.0;
switch (i)
{
case 0:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
*values += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 1:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
*values += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 2:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.210818510677892, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
*values += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 3:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.0, 0.223606797749979};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
*values += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
}
}
/// Evaluate all basis functions at given point x in cell
virtual void evaluate_basis_all(double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Helper variable to hold values of a single dof.
double dof_values = 0.0;
// Loop dofs and call evaluate_basis
for (unsigned int r = 0; r < 4; r++)
{
evaluate_basis(r, &dof_values, x, vertex_coordinates, cell_orientation);
values[r] = dof_values;
}// end loop over 'r'
}
/// Evaluate order n derivatives of basis function i at given point x in cell
virtual void evaluate_basis_derivatives(std::size_t i,
std::size_t n,
double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Compute number of derivatives.
unsigned int num_derivatives = 1;
for (unsigned int r = 0; r < n; r++)
{
num_derivatives *= 3;
}// end loop over 'r'
// Reset values. Assuming that values is always an array.
for (unsigned int r = 0; r < num_derivatives; r++)
{
values[r] = 0.0;
}// end loop over 'r'
// Call evaluate_basis if order of derivatives is equal to zero.
if (n == 0)
{
evaluate_basis(i, values, x, vertex_coordinates, cell_orientation);
return ;
}
// If order of derivatives is greater than the maximum polynomial degree, return zeros.
if (n > 1)
{
return ;
}
// Compute Jacobian
double J[9];
compute_jacobian_tetrahedron_3d(J, vertex_coordinates);
// Compute Jacobian inverse and determinant
double K[9];
double detJ;
compute_jacobian_inverse_tetrahedron_3d(K, detJ, J);
// Compute constants
const double C0 = vertex_coordinates[9] + vertex_coordinates[6] + vertex_coordinates[3] - vertex_coordinates[0];
const double C1 = vertex_coordinates[10] + vertex_coordinates[7] + vertex_coordinates[4] - vertex_coordinates[1];
const double C2 = vertex_coordinates[11] + vertex_coordinates[8] + vertex_coordinates[5] - vertex_coordinates[2];
// Compute subdeterminants
const double d_00 = J[4]*J[8] - J[5]*J[7];
const double d_01 = J[5]*J[6] - J[3]*J[8];
const double d_02 = J[3]*J[7] - J[4]*J[6];
const double d_10 = J[2]*J[7] - J[1]*J[8];
const double d_11 = J[0]*J[8] - J[2]*J[6];
const double d_12 = J[1]*J[6] - J[0]*J[7];
const double d_20 = J[1]*J[5] - J[2]*J[4];
const double d_21 = J[2]*J[3] - J[0]*J[5];
const double d_22 = J[0]*J[4] - J[1]*J[3];
// Get coordinates and map to the reference (FIAT) element
double X = (d_00*(2.0*x[0] - C0) + d_10*(2.0*x[1] - C1) + d_20*(2.0*x[2] - C2)) / detJ;
double Y = (d_01*(2.0*x[0] - C0) + d_11*(2.0*x[1] - C1) + d_21*(2.0*x[2] - C2)) / detJ;
double Z = (d_02*(2.0*x[0] - C0) + d_12*(2.0*x[1] - C1) + d_22*(2.0*x[2] - C2)) / detJ;
// Declare two dimensional array that holds combinations of derivatives and initialise
unsigned int combinations[3][1];
for (unsigned int row = 0; row < 3; row++)
{
for (unsigned int col = 0; col < 1; col++)
combinations[row][col] = 0;
}
// Generate combinations of derivatives
for (unsigned int row = 1; row < num_derivatives; row++)
{
for (unsigned int num = 0; num < row; num++)
{
for (unsigned int col = n-1; col+1 > 0; col--)
{
if (combinations[row][col] + 1 > 2)
combinations[row][col] = 0;
else
{
combinations[row][col] += 1;
break;
}
}
}
}
// Compute inverse of Jacobian
const double Jinv[3][3] = {{K[0], K[1], K[2]}, {K[3], K[4], K[5]}, {K[6], K[7], K[8]}};
// Declare transformation matrix
// Declare pointer to two dimensional array and initialise
double transform[3][3];
for (unsigned int j = 0; j < num_derivatives; j++)
{
for (unsigned int k = 0; k < num_derivatives; k++)
transform[j][k] = 1;
}
// Construct transformation matrix
for (unsigned int row = 0; row < num_derivatives; row++)
{
for (unsigned int col = 0; col < num_derivatives; col++)
{
for (unsigned int k = 0; k < n; k++)
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
}
}
switch (i)
{
case 0:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 1:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 2:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.210818510677892, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 3:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.0, 0.223606797749979};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
}
}
/// Evaluate order n derivatives of all basis functions at given point x in cell
virtual void evaluate_basis_derivatives_all(std::size_t n,
double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Call evaluate_basis_all if order of derivatives is equal to zero.
if (n == 0)
{
evaluate_basis_all(values, x, vertex_coordinates, cell_orientation);
return ;
}
// Compute number of derivatives.
unsigned int num_derivatives = 1;
for (unsigned int r = 0; r < n; r++)
{
num_derivatives *= 3;
}// end loop over 'r'
// Set values equal to zero.
for (unsigned int r = 0; r < 4; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r*num_derivatives + s] = 0.0;
}// end loop over 's'
}// end loop over 'r'
// If order of derivatives is greater than the maximum polynomial degree, return zeros.
if (n > 1)
{
return ;
}
// Helper variable to hold values of a single dof.
double dof_values[3];
for (unsigned int r = 0; r < 3; r++)
{
dof_values[r] = 0.0;
}// end loop over 'r'
// Loop dofs and call evaluate_basis_derivatives.
for (unsigned int r = 0; r < 4; r++)
{
evaluate_basis_derivatives(r, n, dof_values, x, vertex_coordinates, cell_orientation);
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r*num_derivatives + s] = dof_values[s];
}// end loop over 's'
}// end loop over 'r'
}
/// Evaluate linear functional for dof i on the function f
virtual double evaluate_dof(std::size_t i,
const ufc::function& f,
const double* vertex_coordinates,
int cell_orientation,
const ufc::cell& c) const
{
// Declare variables for result of evaluation
double vals[1];
// Declare variable for physical coordinates
double y[3];
switch (i)
{
case 0:
{
y[0] = vertex_coordinates[0];
y[1] = vertex_coordinates[1];
y[2] = vertex_coordinates[2];
f.evaluate(vals, y, c);
return vals[0];
break;
}
case 1:
{
y[0] = vertex_coordinates[3];
y[1] = vertex_coordinates[4];
y[2] = vertex_coordinates[5];
f.evaluate(vals, y, c);
return vals[0];
break;
}
case 2:
{
y[0] = vertex_coordinates[6];
y[1] = vertex_coordinates[7];
y[2] = vertex_coordinates[8];
f.evaluate(vals, y, c);
return vals[0];
break;
}
case 3:
{
y[0] = vertex_coordinates[9];
y[1] = vertex_coordinates[10];
y[2] = vertex_coordinates[11];
f.evaluate(vals, y, c);
return vals[0];
break;
}
}
return 0.0;
}
/// Evaluate linear functionals for all dofs on the function f
virtual void evaluate_dofs(double* values,
const ufc::function& f,
const double* vertex_coordinates,
int cell_orientation,
const ufc::cell& c) const
{
// Declare variables for result of evaluation
double vals[1];
// Declare variable for physical coordinates
double y[3];
y[0] = vertex_coordinates[0];
y[1] = vertex_coordinates[1];
y[2] = vertex_coordinates[2];
f.evaluate(vals, y, c);
values[0] = vals[0];
y[0] = vertex_coordinates[3];
y[1] = vertex_coordinates[4];
y[2] = vertex_coordinates[5];
f.evaluate(vals, y, c);
values[1] = vals[0];
y[0] = vertex_coordinates[6];
y[1] = vertex_coordinates[7];
y[2] = vertex_coordinates[8];
f.evaluate(vals, y, c);
values[2] = vals[0];
y[0] = vertex_coordinates[9];
y[1] = vertex_coordinates[10];
y[2] = vertex_coordinates[11];
f.evaluate(vals, y, c);
values[3] = vals[0];
}
/// Interpolate vertex values from dof values
virtual void interpolate_vertex_values(double* vertex_values,
const double* dof_values,
const double* vertex_coordinates,
int cell_orientation,
const ufc::cell& c) const
{
// Evaluate function and change variables
vertex_values[0] = dof_values[0];
vertex_values[1] = dof_values[1];
vertex_values[2] = dof_values[2];
vertex_values[3] = dof_values[3];
}
/// Map coordinate xhat from reference cell to coordinate x in cell
virtual void map_from_reference_cell(double* x,
const double* xhat,
const ufc::cell& c) const
{
throw std::runtime_error("map_from_reference_cell not yet implemented.");
}
/// Map from coordinate x in cell to coordinate xhat in reference cell
virtual void map_to_reference_cell(double* xhat,
const double* x,
const ufc::cell& c) const
{
throw std::runtime_error("map_to_reference_cell not yet implemented.");
}
/// Return the number of sub elements (for a mixed element)
virtual std::size_t num_sub_elements() const
{
return 0;
}
/// Create a new finite element for sub element i (for a mixed element)
virtual ufc::finite_element* create_sub_element(std::size_t i) const
{
return 0;
}
/// Create a new class instance
virtual ufc::finite_element* create() const
{
return new navierstokes_finite_element_1();
}
};
/// This class defines the interface for a finite element.
class navierstokes_finite_element_2: public ufc::finite_element
{
public:
/// Constructor
navierstokes_finite_element_2() : ufc::finite_element()
{
// Do nothing
}
/// Destructor
virtual ~navierstokes_finite_element_2()
{
// Do nothing
}
/// Return a string identifying the finite element
virtual const char* signature() const
{
return "VectorElement('Lagrange', Domain(Cell('tetrahedron', 3), 'tetrahedron_multiverse', 3, 3), 1, 3, None)";
}
/// Return the cell shape
virtual ufc::shape cell_shape() const
{
return ufc::tetrahedron;
}
/// Return the topological dimension of the cell shape
virtual std::size_t topological_dimension() const
{
return 3;
}
/// Return the geometric dimension of the cell shape
virtual std::size_t geometric_dimension() const
{
return 3;
}
/// Return the dimension of the finite element function space
virtual std::size_t space_dimension() const
{
return 12;
}
/// Return the rank of the value space
virtual std::size_t value_rank() const
{
return 1;
}
/// Return the dimension of the value space for axis i
virtual std::size_t value_dimension(std::size_t i) const
{
switch (i)
{
case 0:
{
return 3;
break;
}
}
return 0;
}
/// Evaluate basis function i at given point x in cell
virtual void evaluate_basis(std::size_t i,
double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Compute Jacobian
double J[9];
compute_jacobian_tetrahedron_3d(J, vertex_coordinates);
// Compute Jacobian inverse and determinant
double K[9];
double detJ;
compute_jacobian_inverse_tetrahedron_3d(K, detJ, J);
// Compute constants
const double C0 = vertex_coordinates[9] + vertex_coordinates[6] + vertex_coordinates[3] - vertex_coordinates[0];
const double C1 = vertex_coordinates[10] + vertex_coordinates[7] + vertex_coordinates[4] - vertex_coordinates[1];
const double C2 = vertex_coordinates[11] + vertex_coordinates[8] + vertex_coordinates[5] - vertex_coordinates[2];
// Compute subdeterminants
const double d_00 = J[4]*J[8] - J[5]*J[7];
const double d_01 = J[5]*J[6] - J[3]*J[8];
const double d_02 = J[3]*J[7] - J[4]*J[6];
const double d_10 = J[2]*J[7] - J[1]*J[8];
const double d_11 = J[0]*J[8] - J[2]*J[6];
const double d_12 = J[1]*J[6] - J[0]*J[7];
const double d_20 = J[1]*J[5] - J[2]*J[4];
const double d_21 = J[2]*J[3] - J[0]*J[5];
const double d_22 = J[0]*J[4] - J[1]*J[3];
// Get coordinates and map to the reference (FIAT) element
double X = (d_00*(2.0*x[0] - C0) + d_10*(2.0*x[1] - C1) + d_20*(2.0*x[2] - C2)) / detJ;
double Y = (d_01*(2.0*x[0] - C0) + d_11*(2.0*x[1] - C1) + d_21*(2.0*x[2] - C2)) / detJ;
double Z = (d_02*(2.0*x[0] - C0) + d_12*(2.0*x[1] - C1) + d_22*(2.0*x[2] - C2)) / detJ;
// Reset values
values[0] = 0.0;
values[1] = 0.0;
values[2] = 0.0;
switch (i)
{
case 0:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[0] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 1:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[0] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 2:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.210818510677892, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[0] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 3:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.0, 0.223606797749979};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[0] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 4:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[1] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 5:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[1] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 6:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.210818510677892, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[1] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 7:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.0, 0.223606797749979};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[1] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 8:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[2] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 9:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[2] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 10:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.210818510677892, -0.074535599249993};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[2] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
case 11:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.0, 0.223606797749979};
// Compute value(s)
for (unsigned int r = 0; r < 4; r++)
{
values[2] += coefficients0[r]*basisvalues[r];
}// end loop over 'r'
break;
}
}
}
/// Evaluate all basis functions at given point x in cell
virtual void evaluate_basis_all(double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Helper variable to hold values of a single dof.
double dof_values[3] = {0.0, 0.0, 0.0};
// Loop dofs and call evaluate_basis
for (unsigned int r = 0; r < 12; r++)
{
evaluate_basis(r, dof_values, x, vertex_coordinates, cell_orientation);
for (unsigned int s = 0; s < 3; s++)
{
values[r*3 + s] = dof_values[s];
}// end loop over 's'
}// end loop over 'r'
}
/// Evaluate order n derivatives of basis function i at given point x in cell
virtual void evaluate_basis_derivatives(std::size_t i,
std::size_t n,
double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Compute number of derivatives.
unsigned int num_derivatives = 1;
for (unsigned int r = 0; r < n; r++)
{
num_derivatives *= 3;
}// end loop over 'r'
// Reset values. Assuming that values is always an array.
for (unsigned int r = 0; r < 3*num_derivatives; r++)
{
values[r] = 0.0;
}// end loop over 'r'
// Call evaluate_basis if order of derivatives is equal to zero.
if (n == 0)
{
evaluate_basis(i, values, x, vertex_coordinates, cell_orientation);
return ;
}
// If order of derivatives is greater than the maximum polynomial degree, return zeros.
if (n > 1)
{
return ;
}
// Compute Jacobian
double J[9];
compute_jacobian_tetrahedron_3d(J, vertex_coordinates);
// Compute Jacobian inverse and determinant
double K[9];
double detJ;
compute_jacobian_inverse_tetrahedron_3d(K, detJ, J);
// Compute constants
const double C0 = vertex_coordinates[9] + vertex_coordinates[6] + vertex_coordinates[3] - vertex_coordinates[0];
const double C1 = vertex_coordinates[10] + vertex_coordinates[7] + vertex_coordinates[4] - vertex_coordinates[1];
const double C2 = vertex_coordinates[11] + vertex_coordinates[8] + vertex_coordinates[5] - vertex_coordinates[2];
// Compute subdeterminants
const double d_00 = J[4]*J[8] - J[5]*J[7];
const double d_01 = J[5]*J[6] - J[3]*J[8];
const double d_02 = J[3]*J[7] - J[4]*J[6];
const double d_10 = J[2]*J[7] - J[1]*J[8];
const double d_11 = J[0]*J[8] - J[2]*J[6];
const double d_12 = J[1]*J[6] - J[0]*J[7];
const double d_20 = J[1]*J[5] - J[2]*J[4];
const double d_21 = J[2]*J[3] - J[0]*J[5];
const double d_22 = J[0]*J[4] - J[1]*J[3];
// Get coordinates and map to the reference (FIAT) element
double X = (d_00*(2.0*x[0] - C0) + d_10*(2.0*x[1] - C1) + d_20*(2.0*x[2] - C2)) / detJ;
double Y = (d_01*(2.0*x[0] - C0) + d_11*(2.0*x[1] - C1) + d_21*(2.0*x[2] - C2)) / detJ;
double Z = (d_02*(2.0*x[0] - C0) + d_12*(2.0*x[1] - C1) + d_22*(2.0*x[2] - C2)) / detJ;
// Declare two dimensional array that holds combinations of derivatives and initialise
unsigned int combinations[3][1];
for (unsigned int row = 0; row < 3; row++)
{
for (unsigned int col = 0; col < 1; col++)
combinations[row][col] = 0;
}
// Generate combinations of derivatives
for (unsigned int row = 1; row < num_derivatives; row++)
{
for (unsigned int num = 0; num < row; num++)
{
for (unsigned int col = n-1; col+1 > 0; col--)
{
if (combinations[row][col] + 1 > 2)
combinations[row][col] = 0;
else
{
combinations[row][col] += 1;
break;
}
}
}
}
// Compute inverse of Jacobian
const double Jinv[3][3] = {{K[0], K[1], K[2]}, {K[3], K[4], K[5]}, {K[6], K[7], K[8]}};
// Declare transformation matrix
// Declare pointer to two dimensional array and initialise
double transform[3][3];
for (unsigned int j = 0; j < num_derivatives; j++)
{
for (unsigned int k = 0; k < num_derivatives; k++)
transform[j][k] = 1;
}
// Construct transformation matrix
for (unsigned int row = 0; row < num_derivatives; row++)
{
for (unsigned int col = 0; col < num_derivatives; col++)
{
for (unsigned int k = 0; k < n; k++)
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
}
}
switch (i)
{
case 0:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 1:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 2:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.210818510677892, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 3:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.0, 0.223606797749979};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 4:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[num_derivatives + r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 5:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[num_derivatives + r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 6:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.210818510677892, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[num_derivatives + r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 7:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.0, 0.223606797749979};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[num_derivatives + r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 8:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[2*num_derivatives + r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 9:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[2*num_derivatives + r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 10:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.210818510677892, -0.074535599249993};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[2*num_derivatives + r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
case 11:
{
// Array of basisvalues
double basisvalues[4] = {0.0, 0.0, 0.0, 0.0};
// Declare helper variables
double tmp0 = 0.5*(2.0 + Y + Z + 2.0*X);
// Compute basisvalues
basisvalues[0] = 1.0;
basisvalues[1] = tmp0;
basisvalues[2] = 0.5*(2.0 + 3.0*Y + Z)*basisvalues[0];
basisvalues[3] = (2.0*Z + 1.0)*basisvalues[0];
basisvalues[0] *= std::sqrt(0.75);
basisvalues[3] *= std::sqrt(1.25);
basisvalues[2] *= std::sqrt(2.5);
basisvalues[1] *= std::sqrt(7.5);
// Table(s) of coefficients
static const double coefficients0[4] = \
{0.288675134594813, 0.0, 0.0, 0.223606797749979};
// Tables of derivatives of the polynomial base (transpose).
static const double dmats0[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{6.32455532033676, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats1[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{5.47722557505166, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0}};
static const double dmats2[4][4] = \
{{0.0, 0.0, 0.0, 0.0},
{3.16227766016838, 0.0, 0.0, 0.0},
{1.82574185835055, 0.0, 0.0, 0.0},
{5.16397779494322, 0.0, 0.0, 0.0}};
// Compute reference derivatives.
// Declare array of derivatives on FIAT element.
double derivatives[3];
for (unsigned int r = 0; r < 3; r++)
{
derivatives[r] = 0.0;
}// end loop over 'r'
// Declare derivative matrix (of polynomial basis).
double dmats[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Declare (auxiliary) derivative matrix (of polynomial basis).
double dmats_old[4][4] = \
{{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}};
// Loop possible derivatives.
for (unsigned int r = 0; r < num_derivatives; r++)
{
// Resetting dmats values to compute next derivative.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats[t][u] = 0.0;
if (t == u)
{
dmats[t][u] = 1.0;
}
}// end loop over 'u'
}// end loop over 't'
// Looping derivative order to generate dmats.
for (unsigned int s = 0; s < n; s++)
{
// Updating dmats_old with new values and resetting dmats.
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
dmats_old[t][u] = dmats[t][u];
dmats[t][u] = 0.0;
}// end loop over 'u'
}// end loop over 't'
// Update dmats using an inner product.
if (combinations[r][s] == 0)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 1)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
if (combinations[r][s] == 2)
{
for (unsigned int t = 0; t < 4; t++)
{
for (unsigned int u = 0; u < 4; u++)
{
for (unsigned int tu = 0; tu < 4; tu++)
{
dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
}// end loop over 'tu'
}// end loop over 'u'
}// end loop over 't'
}
}// end loop over 's'
for (unsigned int s = 0; s < 4; s++)
{
for (unsigned int t = 0; t < 4; t++)
{
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
}// end loop over 't'
}// end loop over 's'
}// end loop over 'r'
// Transform derivatives back to physical element
for (unsigned int r = 0; r < num_derivatives; r++)
{
for (unsigned int s = 0; s < num_derivatives; s++)
{
values[2*num_derivatives + r] += transform[r][s]*derivatives[s];
}// end loop over 's'
}// end loop over 'r'
break;
}
}
}
/// Evaluate order n derivatives of all basis functions at given point x in cell
virtual void evaluate_basis_derivatives_all(std::size_t n,
double* values,
const double* x,
const double* vertex_coordinates,
int cell_orientation) const
{
// Call evaluate_basis_all if order of derivatives is equal to zero.
if (n == 0)
{
evaluate_basis_all(values, x, vertex_coordinates, cell_orientation);
return ;
}
// Compute number of derivatives.
unsigned int num_derivatives = 1;
for (unsigned int r = 0; r < n; r++)
{
num_derivatives *= 3;
}// end loop over 'r'
// Set values equal to zero.
for (unsigned int r = 0; r < 12; r++)
{
for (unsigned int s = 0; s < 3*num_derivatives; s++)
{
values[r*3*num_derivatives + s] = 0.0;
}// end loop over 's'
}// end loop over 'r'
// If order of derivatives is greater than the maximum polynomial degree, return zeros.
if (n > 1)
{
return ;
}
// Helper variable to hold values of a single dof.
double dof_values[9];
for (unsigned int r = 0; r < 9; r++)
{
dof_values[r] = 0.0;
}// end loop over 'r'
// Loop dofs and call evaluate_basis_derivatives.
for (unsigned int r = 0; r < 12; r++)
{
evaluate_basis_derivatives(r, n, dof_values, x, vertex_coordinates, cell_orientation);
for (unsigned int s = 0; s < 3*num_derivatives; s++)
{
values[r*3*num_derivatives + s] = dof_values[s];
}// end loop over 's'
}// end loop over 'r'
}
/// Evaluate linear functional for dof i on the function f
virtual double evaluate_dof(std::size_t i,
const ufc::function& f,
const double* vertex_coordinates,
int cell_orientation,
const ufc::cell& c) const
{
// Declare variables for result of evaluation
double vals[3];
// Declare variable for physical coordinates
double y[3];
switch (i)
{
case 0:
{
y[0] = vertex_coordinates[0];
y[1] = vertex_coordinates[1];
y[2] = vertex_coordinates[2];
f.evaluate(vals, y, c);
return vals[0];
break;
}
case 1:
{
y[0] = vertex_coordinates[3];
y[1] = vertex_coordinates[4];
y[2] = vertex_coordinates[5];
f.evaluate(vals, y, c);
return vals[0];
break;
}
case 2:
{
y[0] = vertex_coordinates[6];
y[1] = vertex_coordinates[7];
y[2] = vertex_coordinates[8];
f.evaluate(vals, y, c);
return vals[0];
break;
}
case 3:
{
y[0] = vertex_coordinates[9];
y[1] = vertex_coordinates[10];
y[2] = vertex_coordinates[11];
f.evaluate(vals, y, c);
return vals[0];
break;
}
case 4:
{
y[0] = vertex_coordinates[0];
y[1] = vertex_coordinates[1];
y[2] = vertex_coordinates[2];
f.evaluate(vals, y, c);
return vals[1];
break;
}
case 5:
{
y[0] = vertex_coordinates[3];
y[1] = vertex_coordinates[4];
y[2] = vertex_coordinates[5];
f.evaluate(vals, y, c);
return vals[1];
break;
}
case 6:
{
y[0] = vertex_coordinates[6];
y[1] = vertex_coordinates[7];
y[2] = vertex_coordinates[8];
f.evaluate(vals, y, c);
return vals[1];
break;
}
case 7:
{
y[0] = vertex_coordinates[9];
y[1] = vertex_coordinates[10];
y[2] = vertex_coordinates[11];
f.evaluate(vals, y, c);
return vals[1];
break;
}
case 8:
{
y[0] = vertex_coordinates[0];
y[1] = vertex_coordinates[1];
y[2] = vertex_coordinates[2];
f.evaluate(vals, y, c);
return vals[2];
break;
}
case 9:
{
y[0] = vertex_coordinates[3];
y[1] = vertex_coordinates[4];
y[2] = vertex_coordinates[5];
f.evaluate(vals, y, c);
return vals[2];
break;
}
case 10:
{
y[0] = vertex_coordinates[6];
y[1] = vertex_coordinates[7];
y[2] = vertex_coordinates[8];
f.evaluate(vals, y, c);
return vals[2];
break;
}
case 11:
{
y[0] = vertex_coordinates[9];
y[1] = vertex_coordinates[10];
y[2] = vertex_coordinates[11];
f.evaluate(vals, y, c);
return vals[2];
break;
}
}
return 0.0;
}
/// Evaluate linear functionals for all dofs on the function f
virtual void evaluate_dofs(double* values,
const ufc::function& f,
const double* vertex_coordinates,
int cell_orientation,
const ufc::cell& c) const
{
// Declare variables for result of evaluation
double vals[3];
// Declare variable for physical coordinates
double y[3];
y[0] = vertex_coordinates[0];
y[1] = vertex_coordinates[1];
y[2] = vertex_coordinates[2];
f.evaluate(vals, y, c);
values[0] = vals[0];
y[0] = vertex_coordinates[3];
y[1] = vertex_coordinates[4];
y[2] = vertex_coordinates[5];
f.evaluate(vals, y, c);
values[1] = vals[0];
y[0] = vertex_coordinates[6];
y[1] = vertex_coordinates[7];
y[2] = vertex_coordinates[8];
f.evaluate(vals, y, c);
values[2] = vals[0];
y[0] = vertex_coordinates[9];
y[1] = vertex_coordinates[10];
y[2] = vertex_coordinates[11];
f.evaluate(vals, y, c);
values[3] = vals[0];
y[0] = vertex_coordinates[0];
y[1] = vertex_coordinates[1];
y[2] = vertex_coordinates[2];
f.evaluate(vals, y, c);
values[4] = vals[1];
y[0] = vertex_coordinates[3];
y[1] = vertex_coordinates[4];
y[2] = vertex_coordinates[5];
f.evaluate(vals, y, c);
values[5] = vals[1];
y[0] = vertex_coordinates[6];
y[1] = vertex_coordinates[7];
y[2] = vertex_coordinates[8];
f.evaluate(vals, y, c);
values[6] = vals[1];
y[0] = vertex_coordinates[9];
y[1] = vertex_coordinates[10];
y[2] = vertex_coordinates[11];
f.evaluate(vals, y, c);
values[7] = vals[1];
y[0] = vertex_coordinates[0];
y[1] = vertex_coordinates[1];
y[2] = vertex_coordinates[2];
f.evaluate(vals, y, c);
values[8] = vals[2];
y[0] = vertex_coordinates[3];
y[1] = vertex_coordinates[4];
y[2] = vertex_coordinates[5];
f.evaluate(vals, y, c);
values[9] = vals[2];
y[0] = vertex_coordinates[6];
y[1] = vertex_coordinates[7];
y[2] = vertex_coordinates[8];
f.evaluate(vals, y, c);
values[10] = vals[2];
y[0] = vertex_coordinates[9];
y[1] = vertex_coordinates[10];
y[2] = vertex_coordinates[11];
f.evaluate(vals, y, c);
values[11] = vals[2];
}
/// Interpolate vertex values from dof values
virtual void interpolate_vertex_values(double* vertex_values,
const double* dof_values,
const double* vertex_coordinates,
int cell_orientation,
const ufc::cell& c) const
{
// Evaluate function and change variables
vertex_values[0] = dof_values[0];
vertex_values[3] = dof_values[1];
vertex_values[6] = dof_values[2];
vertex_values[9] = dof_values[3];
// Evaluate function and change variables
vertex_values[1] = dof_values[4];
vertex_values[4] = dof_values[5];
vertex_values[7] = dof_values[6];
vertex_values[10] = dof_values[7];
// Evaluate function and change variables
vertex_values[2] = dof_values[8];
vertex_values[5] = dof_values[9];
vertex_values[8] = dof_values[10];
vertex_values[11] = dof_values[11];
}
/// Map coordinate xhat from reference cell to coordinate x in cell
virtual void map_from_reference_cell(double* x,
const double* xhat,
const ufc::cell& c) const
{
throw std::runtime_error("map_from_reference_cell not yet implemented.");
}
/// Map from coordinate x in cell to coordinate xhat in reference cell
virtual void map_to_reference_cell(double* xhat,
const double* x,
const ufc::cell& c) const
{
throw std::runtime_error("map_to_reference_cell not yet implemented.");
}
/// Return the number of sub elements (for a mixed element)
virtual std::size_t num_sub_elements() const
{
return 3;
}
/// Create a new finite element for sub element i (for a mixed element)
virtual ufc::finite_element* create_sub_element(std::size_t i) const
{
switch (i)
{
case 0:
{
return new navierstokes_finite_element_1();
break;
}
case 1:
{
return new navierstokes_finite_element_1();
break;
}
case 2:
{
return new navierstokes_finite_element_1();
break;
}
}
return 0;
}
/// Create a new class instance
virtual ufc::finite_element* create() const
{
return new navierstokes_finite_element_2();
}
};
/// This class defines the interface for a local-to-global mapping of
/// degrees of freedom (dofs).
class navierstokes_dofmap_0: public ufc::dofmap
{
public:
/// Constructor
navierstokes_dofmap_0() : ufc::dofmap()
{
// Do nothing
}
/// Destructor
virtual ~navierstokes_dofmap_0()
{
// Do nothing
}
/// Return a string identifying the dofmap
virtual const char* signature() const
{
return "FFC dofmap for FiniteElement('Discontinuous Lagrange', Domain(Cell('tetrahedron', 3), 'tetrahedron_multiverse', 3, 3), 0, None)";
}
/// Return true iff mesh entities of topological dimension d are needed
virtual bool needs_mesh_entities(std::size_t d) const
{
switch (d)
{
case 0:
{
return false;
break;
}
case 1:
{
return false;
break;
}
case 2:
{
return false;
break;
}
case 3:
{
return true;
break;
}
}
return false;
}
/// Return the topological dimension of the associated cell shape
virtual std::size_t topological_dimension() const
{
return 3;
}
/// Return the geometric dimension of the associated cell shape
virtual std::size_t geometric_dimension() const
{
return 3;
}
/// Return the dimension of the global finite element function space
virtual std::size_t global_dimension(const std::vector&
num_global_entities) const
{
return num_global_entities[3];
}
/// Return the dimension of the local finite element function space for a cell
virtual std::size_t local_dimension() const
{
return 1;
}
/// Return the number of dofs on each cell facet
virtual std::size_t num_facet_dofs() const
{
return 0;
}
/// Return the number of dofs associated with each cell entity of dimension d
virtual std::size_t num_entity_dofs(std::size_t d) const
{
switch (d)
{
case 0:
{
return 0;
break;
}
case 1:
{
return 0;
break;
}
case 2:
{
return 0;
break;
}
case 3:
{
return 1;
break;
}
}
return 0;
}
/// Tabulate the local-to-global mapping of dofs on a cell
virtual void tabulate_dofs(std::size_t* dofs,
const std::vector& num_global_entities,
const ufc::cell& c) const
{
dofs[0] = c.entity_indices[3][0];
}
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
virtual void tabulate_facet_dofs(std::size_t* dofs,
std::size_t facet) const
{
switch (facet)
{
case 0:
{
break;
}
case 1:
{
break;
}
case 2:
{
break;
}
case 3:
{
break;
}
}
}
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
virtual void tabulate_entity_dofs(std::size_t* dofs,
std::size_t d, std::size_t i) const
{
if (d > 3)
{
throw std::runtime_error("d is larger than dimension (3)");
}
switch (d)
{
case 0:
{
break;
}
case 1:
{
break;
}
case 2:
{
break;
}
case 3:
{
if (i > 0)
{
throw std::runtime_error("i is larger than number of entities (0)");
}
dofs[0] = 0;
break;
}
}
}
/// Tabulate the coordinates of all dofs on a cell
virtual void tabulate_coordinates(double** dof_coordinates,
const double* vertex_coordinates) const
{
dof_coordinates[0][0] = 0.25*vertex_coordinates[0] + 0.25*vertex_coordinates[3] + 0.25*vertex_coordinates[6] + 0.25*vertex_coordinates[9];
dof_coordinates[0][1] = 0.25*vertex_coordinates[1] + 0.25*vertex_coordinates[4] + 0.25*vertex_coordinates[7] + 0.25*vertex_coordinates[10];
dof_coordinates[0][2] = 0.25*vertex_coordinates[2] + 0.25*vertex_coordinates[5] + 0.25*vertex_coordinates[8] + 0.25*vertex_coordinates[11];
}
/// Return the number of sub dofmaps (for a mixed element)
virtual std::size_t num_sub_dofmaps() const
{
return 0;
}
/// Create a new dofmap for sub dofmap i (for a mixed element)
virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
{
return 0;
}
/// Create a new class instance
virtual ufc::dofmap* create() const
{
return new navierstokes_dofmap_0();
}
};
/// This class defines the interface for a local-to-global mapping of
/// degrees of freedom (dofs).
class navierstokes_dofmap_1: public ufc::dofmap
{
public:
/// Constructor
navierstokes_dofmap_1() : ufc::dofmap()
{
// Do nothing
}
/// Destructor
virtual ~navierstokes_dofmap_1()
{
// Do nothing
}
/// Return a string identifying the dofmap
virtual const char* signature() const
{
return "FFC dofmap for FiniteElement('Lagrange', Domain(Cell('tetrahedron', 3), 'tetrahedron_multiverse', 3, 3), 1, None)";
}
/// Return true iff mesh entities of topological dimension d are needed
virtual bool needs_mesh_entities(std::size_t d) const
{
switch (d)
{
case 0:
{
return true;
break;
}
case 1:
{
return false;
break;
}
case 2:
{
return false;
break;
}
case 3:
{
return false;
break;
}
}
return false;
}
/// Return the topological dimension of the associated cell shape
virtual std::size_t topological_dimension() const
{
return 3;
}
/// Return the geometric dimension of the associated cell shape
virtual std::size_t geometric_dimension() const
{
return 3;
}
/// Return the dimension of the global finite element function space
virtual std::size_t global_dimension(const std::vector&
num_global_entities) const
{
return num_global_entities[0];
}
/// Return the dimension of the local finite element function space for a cell
virtual std::size_t local_dimension() const
{
return 4;
}
/// Return the number of dofs on each cell facet
virtual std::size_t num_facet_dofs() const
{
return 3;
}
/// Return the number of dofs associated with each cell entity of dimension d
virtual std::size_t num_entity_dofs(std::size_t d) const
{
switch (d)
{
case 0:
{
return 1;
break;
}
case 1:
{
return 0;
break;
}
case 2:
{
return 0;
break;
}
case 3:
{
return 0;
break;
}
}
return 0;
}
/// Tabulate the local-to-global mapping of dofs on a cell
virtual void tabulate_dofs(std::size_t* dofs,
const std::vector& num_global_entities,
const ufc::cell& c) const
{
dofs[0] = c.entity_indices[0][0];
dofs[1] = c.entity_indices[0][1];
dofs[2] = c.entity_indices[0][2];
dofs[3] = c.entity_indices[0][3];
}
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
virtual void tabulate_facet_dofs(std::size_t* dofs,
std::size_t facet) const
{
switch (facet)
{
case 0:
{
dofs[0] = 1;
dofs[1] = 2;
dofs[2] = 3;
break;
}
case 1:
{
dofs[0] = 0;
dofs[1] = 2;
dofs[2] = 3;
break;
}
case 2:
{
dofs[0] = 0;
dofs[1] = 1;
dofs[2] = 3;
break;
}
case 3:
{
dofs[0] = 0;
dofs[1] = 1;
dofs[2] = 2;
break;
}
}
}
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
virtual void tabulate_entity_dofs(std::size_t* dofs,
std::size_t d, std::size_t i) const
{
if (d > 3)
{
throw std::runtime_error("d is larger than dimension (3)");
}
switch (d)
{
case 0:
{
if (i > 3)
{
throw std::runtime_error("i is larger than number of entities (3)");
}
switch (i)
{
case 0:
{
dofs[0] = 0;
break;
}
case 1:
{
dofs[0] = 1;
break;
}
case 2:
{
dofs[0] = 2;
break;
}
case 3:
{
dofs[0] = 3;
break;
}
}
break;
}
case 1:
{
break;
}
case 2:
{
break;
}
case 3:
{
break;
}
}
}
/// Tabulate the coordinates of all dofs on a cell
virtual void tabulate_coordinates(double** dof_coordinates,
const double* vertex_coordinates) const
{
dof_coordinates[0][0] = vertex_coordinates[0];
dof_coordinates[0][1] = vertex_coordinates[1];
dof_coordinates[0][2] = vertex_coordinates[2];
dof_coordinates[1][0] = vertex_coordinates[3];
dof_coordinates[1][1] = vertex_coordinates[4];
dof_coordinates[1][2] = vertex_coordinates[5];
dof_coordinates[2][0] = vertex_coordinates[6];
dof_coordinates[2][1] = vertex_coordinates[7];
dof_coordinates[2][2] = vertex_coordinates[8];
dof_coordinates[3][0] = vertex_coordinates[9];
dof_coordinates[3][1] = vertex_coordinates[10];
dof_coordinates[3][2] = vertex_coordinates[11];
}
/// Return the number of sub dofmaps (for a mixed element)
virtual std::size_t num_sub_dofmaps() const
{
return 0;
}
/// Create a new dofmap for sub dofmap i (for a mixed element)
virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
{
return 0;
}
/// Create a new class instance
virtual ufc::dofmap* create() const
{
return new navierstokes_dofmap_1();
}
};
/// This class defines the interface for a local-to-global mapping of
/// degrees of freedom (dofs).
class navierstokes_dofmap_2: public ufc::dofmap
{
public:
/// Constructor
navierstokes_dofmap_2() : ufc::dofmap()
{
// Do nothing
}
/// Destructor
virtual ~navierstokes_dofmap_2()
{
// Do nothing
}
/// Return a string identifying the dofmap
virtual const char* signature() const
{
return "FFC dofmap for VectorElement('Lagrange', Domain(Cell('tetrahedron', 3), 'tetrahedron_multiverse', 3, 3), 1, 3, None)";
}
/// Return true iff mesh entities of topological dimension d are needed
virtual bool needs_mesh_entities(std::size_t d) const
{
switch (d)
{
case 0:
{
return true;
break;
}
case 1:
{
return false;
break;
}
case 2:
{
return false;
break;
}
case 3:
{
return false;
break;
}
}
return false;
}
/// Return the topological dimension of the associated cell shape
virtual std::size_t topological_dimension() const
{
return 3;
}
/// Return the geometric dimension of the associated cell shape
virtual std::size_t geometric_dimension() const
{
return 3;
}
/// Return the dimension of the global finite element function space
virtual std::size_t global_dimension(const std::vector&
num_global_entities) const
{
return 3*num_global_entities[0];
}
/// Return the dimension of the local finite element function space for a cell
virtual std::size_t local_dimension() const
{
return 12;
}
/// Return the number of dofs on each cell facet
virtual std::size_t num_facet_dofs() const
{
return 9;
}
/// Return the number of dofs associated with each cell entity of dimension d
virtual std::size_t num_entity_dofs(std::size_t d) const
{
switch (d)
{
case 0:
{
return 3;
break;
}
case 1:
{
return 0;
break;
}
case 2:
{
return 0;
break;
}
case 3:
{
return 0;
break;
}
}
return 0;
}
/// Tabulate the local-to-global mapping of dofs on a cell
virtual void tabulate_dofs(std::size_t* dofs,
const std::vector& num_global_entities,
const ufc::cell& c) const
{
unsigned int offset = 0;
dofs[0] = offset + c.entity_indices[0][0];
dofs[1] = offset + c.entity_indices[0][1];
dofs[2] = offset + c.entity_indices[0][2];
dofs[3] = offset + c.entity_indices[0][3];
offset += num_global_entities[0];
dofs[4] = offset + c.entity_indices[0][0];
dofs[5] = offset + c.entity_indices[0][1];
dofs[6] = offset + c.entity_indices[0][2];
dofs[7] = offset + c.entity_indices[0][3];
offset += num_global_entities[0];
dofs[8] = offset + c.entity_indices[0][0];
dofs[9] = offset + c.entity_indices[0][1];
dofs[10] = offset + c.entity_indices[0][2];
dofs[11] = offset + c.entity_indices[0][3];
offset += num_global_entities[0];
}
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
virtual void tabulate_facet_dofs(std::size_t* dofs,
std::size_t facet) const
{
switch (facet)
{
case 0:
{
dofs[0] = 1;
dofs[1] = 2;
dofs[2] = 3;
dofs[3] = 5;
dofs[4] = 6;
dofs[5] = 7;
dofs[6] = 9;
dofs[7] = 10;
dofs[8] = 11;
break;
}
case 1:
{
dofs[0] = 0;
dofs[1] = 2;
dofs[2] = 3;
dofs[3] = 4;
dofs[4] = 6;
dofs[5] = 7;
dofs[6] = 8;
dofs[7] = 10;
dofs[8] = 11;
break;
}
case 2:
{
dofs[0] = 0;
dofs[1] = 1;
dofs[2] = 3;
dofs[3] = 4;
dofs[4] = 5;
dofs[5] = 7;
dofs[6] = 8;
dofs[7] = 9;
dofs[8] = 11;
break;
}
case 3:
{
dofs[0] = 0;
dofs[1] = 1;
dofs[2] = 2;
dofs[3] = 4;
dofs[4] = 5;
dofs[5] = 6;
dofs[6] = 8;
dofs[7] = 9;
dofs[8] = 10;
break;
}
}
}
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
virtual void tabulate_entity_dofs(std::size_t* dofs,
std::size_t d, std::size_t i) const
{
if (d > 3)
{
throw std::runtime_error("d is larger than dimension (3)");
}
switch (d)
{
case 0:
{
if (i > 3)
{
throw std::runtime_error("i is larger than number of entities (3)");
}
switch (i)
{
case 0:
{
dofs[0] = 0;
dofs[1] = 4;
dofs[2] = 8;
break;
}
case 1:
{
dofs[0] = 1;
dofs[1] = 5;
dofs[2] = 9;
break;
}
case 2:
{
dofs[0] = 2;
dofs[1] = 6;
dofs[2] = 10;
break;
}
case 3:
{
dofs[0] = 3;
dofs[1] = 7;
dofs[2] = 11;
break;
}
}
break;
}
case 1:
{
break;
}
case 2:
{
break;
}
case 3:
{
break;
}
}
}
/// Tabulate the coordinates of all dofs on a cell
virtual void tabulate_coordinates(double** dof_coordinates,
const double* vertex_coordinates) const
{
dof_coordinates[0][0] = vertex_coordinates[0];
dof_coordinates[0][1] = vertex_coordinates[1];
dof_coordinates[0][2] = vertex_coordinates[2];
dof_coordinates[1][0] = vertex_coordinates[3];
dof_coordinates[1][1] = vertex_coordinates[4];
dof_coordinates[1][2] = vertex_coordinates[5];
dof_coordinates[2][0] = vertex_coordinates[6];
dof_coordinates[2][1] = vertex_coordinates[7];
dof_coordinates[2][2] = vertex_coordinates[8];
dof_coordinates[3][0] = vertex_coordinates[9];
dof_coordinates[3][1] = vertex_coordinates[10];
dof_coordinates[3][2] = vertex_coordinates[11];
dof_coordinates[4][0] = vertex_coordinates[0];
dof_coordinates[4][1] = vertex_coordinates[1];
dof_coordinates[4][2] = vertex_coordinates[2];
dof_coordinates[5][0] = vertex_coordinates[3];
dof_coordinates[5][1] = vertex_coordinates[4];
dof_coordinates[5][2] = vertex_coordinates[5];
dof_coordinates[6][0] = vertex_coordinates[6];
dof_coordinates[6][1] = vertex_coordinates[7];
dof_coordinates[6][2] = vertex_coordinates[8];
dof_coordinates[7][0] = vertex_coordinates[9];
dof_coordinates[7][1] = vertex_coordinates[10];
dof_coordinates[7][2] = vertex_coordinates[11];
dof_coordinates[8][0] = vertex_coordinates[0];
dof_coordinates[8][1] = vertex_coordinates[1];
dof_coordinates[8][2] = vertex_coordinates[2];
dof_coordinates[9][0] = vertex_coordinates[3];
dof_coordinates[9][1] = vertex_coordinates[4];
dof_coordinates[9][2] = vertex_coordinates[5];
dof_coordinates[10][0] = vertex_coordinates[6];
dof_coordinates[10][1] = vertex_coordinates[7];
dof_coordinates[10][2] = vertex_coordinates[8];
dof_coordinates[11][0] = vertex_coordinates[9];
dof_coordinates[11][1] = vertex_coordinates[10];
dof_coordinates[11][2] = vertex_coordinates[11];
}
/// Return the number of sub dofmaps (for a mixed element)
virtual std::size_t num_sub_dofmaps() const
{
return 3;
}
/// Create a new dofmap for sub dofmap i (for a mixed element)
virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
{
switch (i)
{
case 0:
{
return new navierstokes_dofmap_1();
break;
}
case 1:
{
return new navierstokes_dofmap_1();
break;
}
case 2:
{
return new navierstokes_dofmap_1();
break;
}
}
return 0;
}
/// Create a new class instance
virtual ufc::dofmap* create() const
{
return new navierstokes_dofmap_2();
}
};
/// This class defines the interface for the tabulation of the cell
/// tensor corresponding to the local contribution to a form from
/// the integral over a cell.
class navierstokes_cell_integral_0_otherwise: public ufc::cell_integral
{
public:
/// Constructor
navierstokes_cell_integral_0_otherwise() : ufc::cell_integral()
{
// Do nothing
}
/// Destructor
virtual ~navierstokes_cell_integral_0_otherwise()
{
// Do nothing
}
/// Tabulate the tensor for the contribution from a local cell
virtual void tabulate_tensor(double* A,
const double * const * w,
const double* vertex_coordinates,
int cell_orientation) const
{
// Compute Jacobian
double J[9];
compute_jacobian_tetrahedron_3d(J, vertex_coordinates);
// Compute Jacobian inverse and determinant
double K[9];
double detJ;
compute_jacobian_inverse_tetrahedron_3d(K, detJ, J);
// Set scale factor
const double det = std::abs(detJ);
// Cell volume
// Compute circumradius
// Array of quadrature weights.
static const double W4[4] = {0.0416666666666667, 0.0416666666666667, 0.0416666666666667, 0.0416666666666667};
// Quadrature points on the UFC reference element: (0.585410196624969, 0.138196601125011, 0.138196601125011), (0.138196601125011, 0.585410196624969, 0.138196601125011), (0.138196601125011, 0.138196601125011, 0.585410196624969), (0.138196601125011, 0.138196601125011, 0.138196601125011)
// Value of basis functions at quadrature points.
static const double FE1_C0[4][4] = \
{{0.138196601125009, 0.585410196624969, 0.138196601125011, 0.138196601125011},
{0.138196601125009, 0.138196601125011, 0.585410196624969, 0.138196601125011},
{0.138196601125009, 0.138196601125011, 0.138196601125011, 0.585410196624969},
{0.585410196624967, 0.138196601125011, 0.138196601125011, 0.138196601125011}};
// Array of non-zero columns
static const unsigned int nzc0[4] = {0, 1, 2, 3};
// Array of non-zero columns
static const unsigned int nzc4[4] = {4, 5, 6, 7};
// Array of non-zero columns
static const unsigned int nzc8[4] = {8, 9, 10, 11};
static const double FE1_C0_D001[4][2] = \
{{-1.0, 1.0},
{-1.0, 1.0},
{-1.0, 1.0},
{-1.0, 1.0}};
// Array of non-zero columns
static const unsigned int nzc1[2] = {0, 3};
// Array of non-zero columns
static const unsigned int nzc3[2] = {0, 1};
// Array of non-zero columns
static const unsigned int nzc9[2] = {8, 11};
// Array of non-zero columns
static const unsigned int nzc2[2] = {0, 2};
// Array of non-zero columns
static const unsigned int nzc6[2] = {4, 6};
// Array of non-zero columns
static const unsigned int nzc7[2] = {4, 5};
// Array of non-zero columns
static const unsigned int nzc11[2] = {8, 9};
// Array of non-zero columns
static const unsigned int nzc10[2] = {8, 10};
// Array of non-zero columns
static const unsigned int nzc5[2] = {4, 7};
// Reset values in the element tensor.
for (unsigned int r = 0; r < 144; r++)
{
A[r] = 0.0;
}// end loop over 'r'
// Number of operations to compute geometry constants: 567.
double G[90];
G[0] = 0.5*det*w[3][0]*(K[5]*K[5]*w[2][0] + w[4][0]*(K[3]*K[3] + K[4]*K[4] + K[5]*K[5]));
G[1] = 0.5*K[3]*K[3]*det*w[1][0]*w[3][0];
G[2] = K[3]*K[4]*det*w[1][0]*w[3][0];
G[3] = K[3]*K[5]*det*w[1][0]*w[3][0];
G[4] = 0.5*K[4]*K[4]*det*w[1][0]*w[3][0];
G[5] = K[4]*K[5]*det*w[1][0]*w[3][0];
G[6] = 0.5*K[5]*K[5]*det*w[1][0]*w[3][0];
G[7] = 0.5*det*w[3][0]*(K[2]*K[5]*w[2][0] + w[4][0]*(K[0]*K[3] + K[1]*K[4] + K[2]*K[5]));
G[8] = 0.5*K[0]*K[3]*det*w[1][0]*w[3][0];
G[9] = 0.5*det*w[1][0]*w[3][0]*(K[0]*K[4] + K[1]*K[3]);
G[10] = 0.5*det*w[1][0]*w[3][0]*(K[0]*K[5] + K[2]*K[3]);
G[11] = 0.5*K[1]*K[4]*det*w[1][0]*w[3][0];
G[12] = 0.5*det*w[1][0]*w[3][0]*(K[1]*K[5] + K[2]*K[4]);
G[13] = 0.5*K[2]*K[5]*det*w[1][0]*w[3][0];
G[14] = 0.5*K[5]*K[6]*det*w[2][0]*w[3][0];
G[15] = 0.5*K[3]*K[5]*det*w[2][0]*w[3][0];
G[16] = 0.5*K[0]*K[5]*det*w[2][0]*w[3][0];
G[17] = 0.5*K[5]*K[7]*det*w[2][0]*w[3][0];
G[18] = 0.5*K[4]*K[5]*det*w[2][0]*w[3][0];
G[19] = 0.5*K[1]*K[5]*det*w[2][0]*w[3][0];
G[20] = 0.5*det*w[3][0]*(K[5]*K[8]*w[2][0] + w[4][0]*(K[3]*K[6] + K[4]*K[7] + K[5]*K[8]));
G[21] = 0.5*K[3]*K[6]*det*w[1][0]*w[3][0];
G[22] = 0.5*det*w[1][0]*w[3][0]*(K[3]*K[7] + K[4]*K[6]);
G[23] = 0.5*det*w[1][0]*w[3][0]*(K[3]*K[8] + K[5]*K[6]);
G[24] = 0.5*K[4]*K[7]*det*w[1][0]*w[3][0];
G[25] = 0.5*det*w[1][0]*w[3][0]*(K[4]*K[8] + K[5]*K[7]);
G[26] = 0.5*K[5]*K[8]*det*w[1][0]*w[3][0];
G[27] = 0.5*det*w[3][0]*(K[2]*K[2]*w[2][0] + w[4][0]*(K[0]*K[0] + K[1]*K[1] + K[2]*K[2]));
G[28] = 0.5*K[0]*K[0]*det*w[1][0]*w[3][0];
G[29] = K[0]*K[1]*det*w[1][0]*w[3][0];
G[30] = K[0]*K[2]*det*w[1][0]*w[3][0];
G[31] = 0.5*K[1]*K[1]*det*w[1][0]*w[3][0];
G[32] = K[1]*K[2]*det*w[1][0]*w[3][0];
G[33] = 0.5*K[2]*K[2]*det*w[1][0]*w[3][0];
G[34] = 0.5*K[2]*K[6]*det*w[2][0]*w[3][0];
G[35] = 0.5*K[2]*K[3]*det*w[2][0]*w[3][0];
G[36] = 0.5*K[0]*K[2]*det*w[2][0]*w[3][0];
G[37] = 0.5*K[2]*K[7]*det*w[2][0]*w[3][0];
G[38] = 0.5*K[2]*K[4]*det*w[2][0]*w[3][0];
G[39] = 0.5*K[1]*K[2]*det*w[2][0]*w[3][0];
G[40] = 0.5*det*w[3][0]*(K[2]*K[8]*w[2][0] + w[4][0]*(K[0]*K[6] + K[1]*K[7] + K[2]*K[8]));
G[41] = 0.5*K[0]*K[6]*det*w[1][0]*w[3][0];
G[42] = 0.5*det*w[1][0]*w[3][0]*(K[0]*K[7] + K[1]*K[6]);
G[43] = 0.5*det*w[1][0]*w[3][0]*(K[0]*K[8] + K[2]*K[6]);
G[44] = 0.5*K[1]*K[7]*det*w[1][0]*w[3][0];
G[45] = 0.5*det*w[1][0]*w[3][0]*(K[1]*K[8] + K[2]*K[7]);
G[46] = 0.5*K[2]*K[8]*det*w[1][0]*w[3][0];
G[47] = 0.5*det*w[3][0]*(K[6]*K[6]*w[2][0] + w[4][0]*(K[6]*K[6] + K[7]*K[7] + K[8]*K[8]));
G[48] = 0.5*K[6]*K[6]*det*w[1][0]*w[3][0];
G[49] = K[6]*K[7]*det*w[1][0]*w[3][0];
G[50] = K[6]*K[8]*det*w[1][0]*w[3][0];
G[51] = 0.5*K[7]*K[7]*det*w[1][0]*w[3][0];
G[52] = K[7]*K[8]*det*w[1][0]*w[3][0];
G[53] = 0.5*K[8]*K[8]*det*w[1][0]*w[3][0];
G[54] = 0.5*det*w[3][0]*(K[3]*K[6]*w[2][0] + w[4][0]*(K[3]*K[6] + K[4]*K[7] + K[5]*K[8]));
G[55] = 0.5*det*w[3][0]*(K[0]*K[6]*w[2][0] + w[4][0]*(K[0]*K[6] + K[1]*K[7] + K[2]*K[8]));
G[56] = 0.5*K[6]*K[7]*det*w[2][0]*w[3][0];
G[57] = 0.5*K[4]*K[6]*det*w[2][0]*w[3][0];
G[58] = 0.5*K[1]*K[6]*det*w[2][0]*w[3][0];
G[59] = 0.5*K[6]*K[8]*det*w[2][0]*w[3][0];
G[60] = 0.5*det*w[3][0]*(K[3]*K[3]*w[2][0] + w[4][0]*(K[3]*K[3] + K[4]*K[4] + K[5]*K[5]));
G[61] = 0.5*det*w[3][0]*(K[0]*K[3]*w[2][0] + w[4][0]*(K[0]*K[3] + K[1]*K[4] + K[2]*K[5]));
G[62] = 0.5*K[3]*K[7]*det*w[2][0]*w[3][0];
G[63] = 0.5*K[3]*K[4]*det*w[2][0]*w[3][0];
G[64] = 0.5*K[1]*K[3]*det*w[2][0]*w[3][0];
G[65] = 0.5*K[3]*K[8]*det*w[2][0]*w[3][0];
G[66] = 0.5*det*w[3][0]*(K[0]*K[0]*w[2][0] + w[4][0]*(K[0]*K[0] + K[1]*K[1] + K[2]*K[2]));
G[67] = 0.5*K[0]*K[7]*det*w[2][0]*w[3][0];
G[68] = 0.5*K[0]*K[4]*det*w[2][0]*w[3][0];
G[69] = 0.5*K[0]*K[1]*det*w[2][0]*w[3][0];
G[70] = 0.5*K[0]*K[8]*det*w[2][0]*w[3][0];
G[71] = 0.5*det*w[3][0]*(K[7]*K[7]*w[2][0] + w[4][0]*(K[6]*K[6] + K[7]*K[7] + K[8]*K[8]));
G[72] = 0.5*det*w[3][0]*(K[4]*K[7]*w[2][0] + w[4][0]*(K[3]*K[6] + K[4]*K[7] + K[5]*K[8]));
G[73] = 0.5*det*w[3][0]*(K[1]*K[7]*w[2][0] + w[4][0]*(K[0]*K[6] + K[1]*K[7] + K[2]*K[8]));
G[74] = 0.5*K[7]*K[8]*det*w[2][0]*w[3][0];
G[75] = 0.5*det*w[3][0]*(K[4]*K[4]*w[2][0] + w[4][0]*(K[3]*K[3] + K[4]*K[4] + K[5]*K[5]));
G[76] = 0.5*det*w[3][0]*(K[1]*K[4]*w[2][0] + w[4][0]*(K[0]*K[3] + K[1]*K[4] + K[2]*K[5]));
G[77] = 0.5*K[4]*K[8]*det*w[2][0]*w[3][0];
G[78] = 0.5*det*w[3][0]*(K[1]*K[1]*w[2][0] + w[4][0]*(K[0]*K[0] + K[1]*K[1] + K[2]*K[2]));
G[79] = 0.5*K[1]*K[8]*det*w[2][0]*w[3][0];
G[80] = 0.5*det*w[3][0]*(K[8]*K[8]*w[2][0] + w[4][0]*(K[6]*K[6] + K[7]*K[7] + K[8]*K[8]));
G[81] = 0.5*K[6]*det*w[3][0];
G[82] = 0.5*K[7]*det*w[3][0];
G[83] = 0.5*K[8]*det*w[3][0];
G[84] = 0.5*K[3]*det*w[3][0];
G[85] = 0.5*K[4]*det*w[3][0];
G[86] = 0.5*K[5]*det*w[3][0];
G[87] = 0.5*K[0]*det*w[3][0];
G[88] = 0.5*K[1]*det*w[3][0];
G[89] = 0.5*K[2]*det*w[3][0];
// Compute element tensor using UFL quadrature representation
// Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True)
// Loop quadrature points for integral.
// Number of operations to compute element tensor for following IP loop = 6760
for (unsigned int ip = 0; ip < 4; ip++)
{
// Coefficient declarations.
double F0 = 0.0;
double F1 = 0.0;
double F2 = 0.0;
// Total number of operations to compute function values = 24
for (unsigned int r = 0; r < 4; r++)
{
F0 += FE1_C0[ip][r]*w[0][nzc0[r]];
F1 += FE1_C0[ip][r]*w[0][nzc4[r]];
F2 += FE1_C0[ip][r]*w[0][nzc8[r]];
}// end loop over 'r'
// Number of operations to compute ip constants: 334
double I[49];
// Number of operations: 16
I[0] = W4[ip]*(G[0] + F0*F0*G[1] + F1*(F0*G[2] + F1*G[4]) + F2*(F0*G[3] + F1*G[5] + F2*G[6]));
// Number of operations: 16
I[1] = W4[ip]*(G[7] + F0*F0*G[8] + F1*(F0*G[9] + F1*G[11]) + F2*(F0*G[10] + F1*G[12] + F2*G[13]));
// Number of operations: 1
I[2] = G[14]*W4[ip];
// Number of operations: 1
I[3] = G[15]*W4[ip];
// Number of operations: 1
I[4] = G[16]*W4[ip];
// Number of operations: 1
I[5] = G[17]*W4[ip];
// Number of operations: 1
I[6] = G[18]*W4[ip];
// Number of operations: 1
I[7] = G[19]*W4[ip];
// Number of operations: 16
I[8] = W4[ip]*(G[20] + F0*F0*G[21] + F1*(F0*G[22] + F1*G[24]) + F2*(F0*G[23] + F1*G[25] + F2*G[26]));
// Number of operations: 16
I[9] = W4[ip]*(G[27] + F0*F0*G[28] + F1*(F0*G[29] + F1*G[31]) + F2*(F0*G[30] + F1*G[32] + F2*G[33]));
// Number of operations: 1
I[10] = G[34]*W4[ip];
// Number of operations: 1
I[11] = G[35]*W4[ip];
// Number of operations: 1
I[12] = G[36]*W4[ip];
// Number of operations: 1
I[13] = G[37]*W4[ip];
// Number of operations: 1
I[14] = G[38]*W4[ip];
// Number of operations: 1
I[15] = G[39]*W4[ip];
// Number of operations: 16
I[16] = W4[ip]*(G[40] + F0*F0*G[41] + F1*(F0*G[42] + F1*G[44]) + F2*(F0*G[43] + F1*G[45] + F2*G[46]));
// Number of operations: 16
I[17] = W4[ip]*(G[47] + F0*F0*G[48] + F1*(F0*G[49] + F1*G[51]) + F2*(F0*G[50] + F1*G[52] + F2*G[53]));
// Number of operations: 16
I[18] = W4[ip]*(G[54] + F0*F0*G[21] + F1*(F0*G[22] + F1*G[24]) + F2*(F0*G[23] + F1*G[25] + F2*G[26]));
// Number of operations: 16
I[19] = W4[ip]*(G[55] + F0*F0*G[41] + F1*(F0*G[42] + F1*G[44]) + F2*(F0*G[43] + F1*G[45] + F2*G[46]));
// Number of operations: 1
I[20] = G[56]*W4[ip];
// Number of operations: 1
I[21] = G[57]*W4[ip];
// Number of operations: 1
I[22] = G[58]*W4[ip];
// Number of operations: 1
I[23] = G[59]*W4[ip];
// Number of operations: 16
I[24] = W4[ip]*(G[60] + F0*F0*G[1] + F1*(F0*G[2] + F1*G[4]) + F2*(F0*G[3] + F1*G[5] + F2*G[6]));
// Number of operations: 16
I[25] = W4[ip]*(G[61] + F0*F0*G[8] + F1*(F0*G[9] + F1*G[11]) + F2*(F0*G[10] + F1*G[12] + F2*G[13]));
// Number of operations: 1
I[26] = G[62]*W4[ip];
// Number of operations: 1
I[27] = G[63]*W4[ip];
// Number of operations: 1
I[28] = G[64]*W4[ip];
// Number of operations: 1
I[29] = G[65]*W4[ip];
// Number of operations: 16
I[30] = W4[ip]*(G[66] + F0*F0*G[28] + F1*(F0*G[29] + F1*G[31]) + F2*(F0*G[30] + F1*G[32] + F2*G[33]));
// Number of operations: 1
I[31] = G[67]*W4[ip];
// Number of operations: 1
I[32] = G[68]*W4[ip];
// Number of operations: 1
I[33] = G[69]*W4[ip];
// Number of operations: 1
I[34] = G[70]*W4[ip];
// Number of operations: 16
I[35] = W4[ip]*(G[71] + F0*F0*G[48] + F1*(F0*G[49] + F1*G[51]) + F2*(F0*G[50] + F1*G[52] + F2*G[53]));
// Number of operations: 16
I[36] = W4[ip]*(G[72] + F0*F0*G[21] + F1*(F0*G[22] + F1*G[24]) + F2*(F0*G[23] + F1*G[25] + F2*G[26]));
// Number of operations: 16
I[37] = W4[ip]*(G[73] + F0*F0*G[41] + F1*(F0*G[42] + F1*G[44]) + F2*(F0*G[43] + F1*G[45] + F2*G[46]));
// Number of operations: 1
I[38] = G[74]*W4[ip];
// Number of operations: 16
I[39] = W4[ip]*(G[75] + F0*F0*G[1] + F1*(F0*G[2] + F1*G[4]) + F2*(F0*G[3] + F1*G[5] + F2*G[6]));
// Number of operations: 16
I[40] = W4[ip]*(G[76] + F0*F0*G[8] + F1*(F0*G[9] + F1*G[11]) + F2*(F0*G[10] + F1*G[12] + F2*G[13]));
// Number of operations: 1
I[41] = G[77]*W4[ip];
// Number of operations: 16
I[42] = W4[ip]*(G[78] + F0*F0*G[28] + F1*(F0*G[29] + F1*G[31]) + F2*(F0*G[30] + F1*G[32] + F2*G[33]));
// Number of operations: 1
I[43] = G[79]*W4[ip];
// Number of operations: 16
I[44] = W4[ip]*(G[80] + F0*F0*G[48] + F1*(F0*G[49] + F1*G[51]) + F2*(F0*G[50] + F1*G[52] + F2*G[53]));
// Number of operations: 6
I[45] = W4[ip]*(F0*G[81] + F1*G[82] + F2*G[83]);
// Number of operations: 6
I[46] = W4[ip]*(F0*G[84] + F1*G[85] + F2*G[86]);
// Number of operations: 6
I[47] = W4[ip]*(F0*G[87] + F1*G[88] + F2*G[89]);
// Number of operations: 1
I[48] = W4[ip]*det;
// Number of operations for primary indices: 216
for (unsigned int j = 0; j < 4; j++)
{
for (unsigned int k = 0; k < 2; k++)
{
// Number of operations to compute entry: 3
A[nzc0[j]*12 + nzc1[k]] += FE1_C0[ip][j]*FE1_C0_D001[ip][k]*I[45];
// Number of operations to compute entry: 3
A[nzc0[j]*12 + nzc2[k]] += FE1_C0[ip][j]*FE1_C0_D001[ip][k]*I[46];
// Number of operations to compute entry: 3
A[nzc0[j]*12 + nzc3[k]] += FE1_C0[ip][j]*FE1_C0_D001[ip][k]*I[47];
// Number of operations to compute entry: 3
A[nzc4[j]*12 + nzc5[k]] += FE1_C0[ip][j]*FE1_C0_D001[ip][k]*I[45];
// Number of operations to compute entry: 3
A[nzc4[j]*12 + nzc6[k]] += FE1_C0[ip][j]*FE1_C0_D001[ip][k]*I[46];
// Number of operations to compute entry: 3
A[nzc4[j]*12 + nzc7[k]] += FE1_C0[ip][j]*FE1_C0_D001[ip][k]*I[47];
// Number of operations to compute entry: 3
A[nzc8[j]*12 + nzc10[k]] += FE1_C0[ip][j]*FE1_C0_D001[ip][k]*I[46];
// Number of operations to compute entry: 3
A[nzc8[j]*12 + nzc11[k]] += FE1_C0[ip][j]*FE1_C0_D001[ip][k]*I[47];
// Number of operations to compute entry: 3
A[nzc8[j]*12 + nzc9[k]] += FE1_C0[ip][j]*FE1_C0_D001[ip][k]*I[45];
}// end loop over 'k'
}// end loop over 'j'
// Number of operations for primary indices: 972
for (unsigned int j = 0; j < 2; j++)
{
for (unsigned int k = 0; k < 2; k++)
{
// Number of operations to compute entry: 3
A[nzc10[j]*12 + nzc10[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[0];
// Number of operations to compute entry: 3
A[nzc10[j]*12 + nzc11[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[1];
// Number of operations to compute entry: 3
A[nzc10[j]*12 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[2];
// Number of operations to compute entry: 3
A[nzc10[j]*12 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[3];
// Number of operations to compute entry: 3
A[nzc10[j]*12 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[4];
// Number of operations to compute entry: 3
A[nzc10[j]*12 + nzc5[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[5];
// Number of operations to compute entry: 3
A[nzc10[j]*12 + nzc6[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[6];
// Number of operations to compute entry: 3
A[nzc10[j]*12 + nzc7[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[7];
// Number of operations to compute entry: 3
A[nzc10[j]*12 + nzc9[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[8];
// Number of operations to compute entry: 3
A[nzc11[j]*12 + nzc10[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[1];
// Number of operations to compute entry: 3
A[nzc11[j]*12 + nzc11[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[9];
// Number of operations to compute entry: 3
A[nzc11[j]*12 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[10];
// Number of operations to compute entry: 3
A[nzc11[j]*12 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[11];
// Number of operations to compute entry: 3
A[nzc11[j]*12 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[12];
// Number of operations to compute entry: 3
A[nzc11[j]*12 + nzc5[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[13];
// Number of operations to compute entry: 3
A[nzc11[j]*12 + nzc6[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[14];
// Number of operations to compute entry: 3
A[nzc11[j]*12 + nzc7[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[15];
// Number of operations to compute entry: 3
A[nzc11[j]*12 + nzc9[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[16];
// Number of operations to compute entry: 3
A[nzc1[j]*12 + nzc10[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[2];
// Number of operations to compute entry: 3
A[nzc1[j]*12 + nzc11[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[10];
// Number of operations to compute entry: 3
A[nzc1[j]*12 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[17];
// Number of operations to compute entry: 3
A[nzc1[j]*12 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[18];
// Number of operations to compute entry: 3
A[nzc1[j]*12 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[19];
// Number of operations to compute entry: 3
A[nzc1[j]*12 + nzc5[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[20];
// Number of operations to compute entry: 3
A[nzc1[j]*12 + nzc6[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[21];
// Number of operations to compute entry: 3
A[nzc1[j]*12 + nzc7[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[22];
// Number of operations to compute entry: 3
A[nzc1[j]*12 + nzc9[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[23];
// Number of operations to compute entry: 3
A[nzc2[j]*12 + nzc10[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[3];
// Number of operations to compute entry: 3
A[nzc2[j]*12 + nzc11[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[11];
// Number of operations to compute entry: 3
A[nzc2[j]*12 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[18];
// Number of operations to compute entry: 3
A[nzc2[j]*12 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[24];
// Number of operations to compute entry: 3
A[nzc2[j]*12 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[25];
// Number of operations to compute entry: 3
A[nzc2[j]*12 + nzc5[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[26];
// Number of operations to compute entry: 3
A[nzc2[j]*12 + nzc6[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[27];
// Number of operations to compute entry: 3
A[nzc2[j]*12 + nzc7[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[28];
// Number of operations to compute entry: 3
A[nzc2[j]*12 + nzc9[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[29];
// Number of operations to compute entry: 3
A[nzc3[j]*12 + nzc10[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[4];
// Number of operations to compute entry: 3
A[nzc3[j]*12 + nzc11[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[12];
// Number of operations to compute entry: 3
A[nzc3[j]*12 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[19];
// Number of operations to compute entry: 3
A[nzc3[j]*12 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[25];
// Number of operations to compute entry: 3
A[nzc3[j]*12 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[30];
// Number of operations to compute entry: 3
A[nzc3[j]*12 + nzc5[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[31];
// Number of operations to compute entry: 3
A[nzc3[j]*12 + nzc6[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[32];
// Number of operations to compute entry: 3
A[nzc3[j]*12 + nzc7[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[33];
// Number of operations to compute entry: 3
A[nzc3[j]*12 + nzc9[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[34];
// Number of operations to compute entry: 3
A[nzc5[j]*12 + nzc10[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[5];
// Number of operations to compute entry: 3
A[nzc5[j]*12 + nzc11[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[13];
// Number of operations to compute entry: 3
A[nzc5[j]*12 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[20];
// Number of operations to compute entry: 3
A[nzc5[j]*12 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[26];
// Number of operations to compute entry: 3
A[nzc5[j]*12 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[31];
// Number of operations to compute entry: 3
A[nzc5[j]*12 + nzc5[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[35];
// Number of operations to compute entry: 3
A[nzc5[j]*12 + nzc6[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[36];
// Number of operations to compute entry: 3
A[nzc5[j]*12 + nzc7[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[37];
// Number of operations to compute entry: 3
A[nzc5[j]*12 + nzc9[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[38];
// Number of operations to compute entry: 3
A[nzc6[j]*12 + nzc10[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[6];
// Number of operations to compute entry: 3
A[nzc6[j]*12 + nzc11[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[14];
// Number of operations to compute entry: 3
A[nzc6[j]*12 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[21];
// Number of operations to compute entry: 3
A[nzc6[j]*12 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[27];
// Number of operations to compute entry: 3
A[nzc6[j]*12 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[32];
// Number of operations to compute entry: 3
A[nzc6[j]*12 + nzc5[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[36];
// Number of operations to compute entry: 3
A[nzc6[j]*12 + nzc6[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[39];
// Number of operations to compute entry: 3
A[nzc6[j]*12 + nzc7[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[40];
// Number of operations to compute entry: 3
A[nzc6[j]*12 + nzc9[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[41];
// Number of operations to compute entry: 3
A[nzc7[j]*12 + nzc10[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[7];
// Number of operations to compute entry: 3
A[nzc7[j]*12 + nzc11[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[15];
// Number of operations to compute entry: 3
A[nzc7[j]*12 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[22];
// Number of operations to compute entry: 3
A[nzc7[j]*12 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[28];
// Number of operations to compute entry: 3
A[nzc7[j]*12 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[33];
// Number of operations to compute entry: 3
A[nzc7[j]*12 + nzc5[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[37];
// Number of operations to compute entry: 3
A[nzc7[j]*12 + nzc6[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[40];
// Number of operations to compute entry: 3
A[nzc7[j]*12 + nzc7[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[42];
// Number of operations to compute entry: 3
A[nzc7[j]*12 + nzc9[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[43];
// Number of operations to compute entry: 3
A[nzc9[j]*12 + nzc10[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[8];
// Number of operations to compute entry: 3
A[nzc9[j]*12 + nzc11[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[16];
// Number of operations to compute entry: 3
A[nzc9[j]*12 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[23];
// Number of operations to compute entry: 3
A[nzc9[j]*12 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[29];
// Number of operations to compute entry: 3
A[nzc9[j]*12 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[34];
// Number of operations to compute entry: 3
A[nzc9[j]*12 + nzc5[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[38];
// Number of operations to compute entry: 3
A[nzc9[j]*12 + nzc6[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[41];
// Number of operations to compute entry: 3
A[nzc9[j]*12 + nzc7[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[43];
// Number of operations to compute entry: 3
A[nzc9[j]*12 + nzc9[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*I[44];
}// end loop over 'k'
}// end loop over 'j'
// Number of operations for primary indices: 144
for (unsigned int j = 0; j < 4; j++)
{
for (unsigned int k = 0; k < 4; k++)
{
// Number of operations to compute entry: 3
A[nzc0[j]*12 + nzc0[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*I[48];
// Number of operations to compute entry: 3
A[nzc4[j]*12 + nzc4[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*I[48];
// Number of operations to compute entry: 3
A[nzc8[j]*12 + nzc8[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*I[48];
}// end loop over 'k'
}// end loop over 'j'
}// end loop over 'ip'
}
};
/// This class defines the interface for the assembly of the global
/// tensor corresponding to a form with r + n arguments, that is, a
/// mapping
///
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
///
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
/// global tensor A is defined by
///
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
///
/// where each argument Vj represents the application to the
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
/// fixed functions (coefficients).
class navierstokes_form_0: public ufc::form
{
public:
/// Constructor
navierstokes_form_0() : ufc::form()
{
// Do nothing
}
/// Destructor
virtual ~navierstokes_form_0()
{
// Do nothing
}
/// Return a string identifying the form
virtual const char* signature() const
{
return "2789002b2213385d6c8d99e802caca1c30b8147b23cefc76f0916136abb500848ab1ef93f03b08383fa01955f7c80e7a03c9c5fbdf89d1262330a8408fc687de";
}
/// Return the rank of the global tensor (r)
virtual std::size_t rank() const
{
return 2;
}
/// Return the number of coefficients (n)
virtual std::size_t num_coefficients() const
{
return 5;
}
/// Return the number of cell domains
virtual std::size_t num_cell_domains() const
{
return 0;
}
/// Return the number of exterior facet domains
virtual std::size_t num_exterior_facet_domains() const
{
return 0;
}
/// Return the number of interior facet domains
virtual std::size_t num_interior_facet_domains() const
{
return 0;
}
/// Return the number of point domains
virtual std::size_t num_point_domains() const
{
return 0;
}
/// Return whether the form has any cell integrals
virtual bool has_cell_integrals() const
{
return true;
}
/// Return whether the form has any exterior facet integrals
virtual bool has_exterior_facet_integrals() const
{
return false;
}
/// Return whether the form has any interior facet integrals
virtual bool has_interior_facet_integrals() const
{
return false;
}
/// Return whether the form has any point integrals
virtual bool has_point_integrals() const
{
return false;
}
/// Create a new finite element for argument function i
virtual ufc::finite_element* create_finite_element(std::size_t i) const
{
switch (i)
{
case 0:
{
return new navierstokes_finite_element_2();
break;
}
case 1:
{
return new navierstokes_finite_element_2();
break;
}
case 2:
{
return new navierstokes_finite_element_2();
break;
}
case 3:
{
return new navierstokes_finite_element_0();
break;
}
case 4:
{
return new navierstokes_finite_element_0();
break;
}
case 5:
{
return new navierstokes_finite_element_0();
break;
}
case 6:
{
return new navierstokes_finite_element_0();
break;
}
}
return 0;
}
/// Create a new dofmap for argument function i
virtual ufc::dofmap* create_dofmap(std::size_t i) const
{
switch (i)
{
case 0:
{
return new navierstokes_dofmap_2();
break;
}
case 1:
{
return new navierstokes_dofmap_2();
break;
}
case 2:
{
return new navierstokes_dofmap_2();
break;
}
case 3:
{
return new navierstokes_dofmap_0();
break;
}
case 4:
{
return new navierstokes_dofmap_0();
break;
}
case 5:
{
return new navierstokes_dofmap_0();
break;
}
case 6:
{
return new navierstokes_dofmap_0();
break;
}
}
return 0;
}
/// Create a new cell integral on sub domain i
virtual ufc::cell_integral* create_cell_integral(std::size_t i) const
{
return 0;
}
/// Create a new exterior facet integral on sub domain i
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(std::size_t i) const
{
return 0;
}
/// Create a new interior facet integral on sub domain i
virtual ufc::interior_facet_integral* create_interior_facet_integral(std::size_t i) const
{
return 0;
}
/// Create a new point integral on sub domain i
virtual ufc::point_integral* create_point_integral(std::size_t i) const
{
return 0;
}
/// Create a new cell integral on everywhere else
virtual ufc::cell_integral* create_default_cell_integral() const
{
return new navierstokes_cell_integral_0_otherwise();
}
/// Create a new exterior facet integral on everywhere else
virtual ufc::exterior_facet_integral* create_default_exterior_facet_integral() const
{
return 0;
}
/// Create a new interior facet integral on everywhere else
virtual ufc::interior_facet_integral* create_default_interior_facet_integral() const
{
return 0;
}
/// Create a new point integral on everywhere else
virtual ufc::point_integral* create_default_point_integral() const
{
return 0;
}
};
// DOLFIN wrappers
// Standard library includes
#include
// DOLFIN includes
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace NavierStokes
{
class CoefficientSpace_d1: public dolfin::FunctionSpace
{
public:
//--- Constructors for standard function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_d1(const dolfin::Mesh& mesh):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), mesh)))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_d1(boost::shared_ptr mesh):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), *mesh)))
{
// Do nothing
}
//--- Constructors for constrained function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_d1(const dolfin::Mesh& mesh, const dolfin::SubDomain& constrained_domain):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), mesh,
dolfin::reference_to_no_delete_pointer(constrained_domain))))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_d1(boost::shared_ptr mesh, boost::shared_ptr constrained_domain):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), *mesh, constrained_domain)))
{
// Do nothing
}
//--- Constructors for restricted function space, 2 different versions ---
// Create restricted function space (reference version)
CoefficientSpace_d1(const dolfin::Restriction& restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction.mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()),
reference_to_no_delete_pointer(restriction))))
{
// Do nothing
}
// Create restricted function space (shared pointer version)
CoefficientSpace_d1(boost::shared_ptr restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction->mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()),
restriction)))
{
// Do nothing
}
// Copy constructor
~CoefficientSpace_d1()
{
}
};
class CoefficientSpace_d2: public dolfin::FunctionSpace
{
public:
//--- Constructors for standard function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_d2(const dolfin::Mesh& mesh):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), mesh)))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_d2(boost::shared_ptr mesh):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), *mesh)))
{
// Do nothing
}
//--- Constructors for constrained function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_d2(const dolfin::Mesh& mesh, const dolfin::SubDomain& constrained_domain):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), mesh,
dolfin::reference_to_no_delete_pointer(constrained_domain))))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_d2(boost::shared_ptr mesh, boost::shared_ptr constrained_domain):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), *mesh, constrained_domain)))
{
// Do nothing
}
//--- Constructors for restricted function space, 2 different versions ---
// Create restricted function space (reference version)
CoefficientSpace_d2(const dolfin::Restriction& restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction.mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()),
reference_to_no_delete_pointer(restriction))))
{
// Do nothing
}
// Create restricted function space (shared pointer version)
CoefficientSpace_d2(boost::shared_ptr restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction->mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()),
restriction)))
{
// Do nothing
}
// Copy constructor
~CoefficientSpace_d2()
{
}
};
class CoefficientSpace_k: public dolfin::FunctionSpace
{
public:
//--- Constructors for standard function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_k(const dolfin::Mesh& mesh):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), mesh)))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_k(boost::shared_ptr mesh):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), *mesh)))
{
// Do nothing
}
//--- Constructors for constrained function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_k(const dolfin::Mesh& mesh, const dolfin::SubDomain& constrained_domain):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), mesh,
dolfin::reference_to_no_delete_pointer(constrained_domain))))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_k(boost::shared_ptr mesh, boost::shared_ptr constrained_domain):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), *mesh, constrained_domain)))
{
// Do nothing
}
//--- Constructors for restricted function space, 2 different versions ---
// Create restricted function space (reference version)
CoefficientSpace_k(const dolfin::Restriction& restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction.mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()),
reference_to_no_delete_pointer(restriction))))
{
// Do nothing
}
// Create restricted function space (shared pointer version)
CoefficientSpace_k(boost::shared_ptr restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction->mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()),
restriction)))
{
// Do nothing
}
// Copy constructor
~CoefficientSpace_k()
{
}
};
class CoefficientSpace_nu: public dolfin::FunctionSpace
{
public:
//--- Constructors for standard function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_nu(const dolfin::Mesh& mesh):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), mesh)))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_nu(boost::shared_ptr mesh):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), *mesh)))
{
// Do nothing
}
//--- Constructors for constrained function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_nu(const dolfin::Mesh& mesh, const dolfin::SubDomain& constrained_domain):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), mesh,
dolfin::reference_to_no_delete_pointer(constrained_domain))))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_nu(boost::shared_ptr mesh, boost::shared_ptr constrained_domain):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()), *mesh, constrained_domain)))
{
// Do nothing
}
//--- Constructors for restricted function space, 2 different versions ---
// Create restricted function space (reference version)
CoefficientSpace_nu(const dolfin::Restriction& restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction.mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()),
reference_to_no_delete_pointer(restriction))))
{
// Do nothing
}
// Create restricted function space (shared pointer version)
CoefficientSpace_nu(boost::shared_ptr restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction->mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_0()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_0()),
restriction)))
{
// Do nothing
}
// Copy constructor
~CoefficientSpace_nu()
{
}
};
class CoefficientSpace_w: public dolfin::FunctionSpace
{
public:
//--- Constructors for standard function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_w(const dolfin::Mesh& mesh):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()), mesh)))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_w(boost::shared_ptr mesh):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()), *mesh)))
{
// Do nothing
}
//--- Constructors for constrained function space, 2 different versions ---
// Create standard function space (reference version)
CoefficientSpace_w(const dolfin::Mesh& mesh, const dolfin::SubDomain& constrained_domain):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()), mesh,
dolfin::reference_to_no_delete_pointer(constrained_domain))))
{
// Do nothing
}
// Create standard function space (shared pointer version)
CoefficientSpace_w(boost::shared_ptr mesh, boost::shared_ptr constrained_domain):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()), *mesh, constrained_domain)))
{
// Do nothing
}
//--- Constructors for restricted function space, 2 different versions ---
// Create restricted function space (reference version)
CoefficientSpace_w(const dolfin::Restriction& restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction.mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()),
reference_to_no_delete_pointer(restriction))))
{
// Do nothing
}
// Create restricted function space (shared pointer version)
CoefficientSpace_w(boost::shared_ptr restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction->mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()),
restriction)))
{
// Do nothing
}
// Copy constructor
~CoefficientSpace_w()
{
}
};
class Form_a_FunctionSpace_0: public dolfin::FunctionSpace
{
public:
//--- Constructors for standard function space, 2 different versions ---
// Create standard function space (reference version)
Form_a_FunctionSpace_0(const dolfin::Mesh& mesh):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()), mesh)))
{
// Do nothing
}
// Create standard function space (shared pointer version)
Form_a_FunctionSpace_0(boost::shared_ptr mesh):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()), *mesh)))
{
// Do nothing
}
//--- Constructors for constrained function space, 2 different versions ---
// Create standard function space (reference version)
Form_a_FunctionSpace_0(const dolfin::Mesh& mesh, const dolfin::SubDomain& constrained_domain):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()), mesh,
dolfin::reference_to_no_delete_pointer(constrained_domain))))
{
// Do nothing
}
// Create standard function space (shared pointer version)
Form_a_FunctionSpace_0(boost::shared_ptr mesh, boost::shared_ptr constrained_domain):
dolfin::FunctionSpace(mesh,
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr(new navierstokes_finite_element_2()))),
boost::shared_ptr(new dolfin::DofMap(boost::shared_ptr(new navierstokes_dofmap_2()), *mesh, constrained_domain)))
{
// Do nothing
}
//--- Constructors for restricted function space, 2 different versions ---
// Create restricted function space (reference version)
Form_a_FunctionSpace_0(const dolfin::Restriction& restriction):
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(restriction.mesh()),
boost::shared_ptr(new dolfin::FiniteElement(boost::shared_ptr